authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-04-21 09:49:20-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-04-21 09:49:20-04:00
logbd5831ce0e033662fed1adf98e81e7d058c6f883
tree6d7f915268e23ae56e33a713b1be3ac7560a949e
parent1a1b5ee264d8b2219c34d53cc9602692e6d2ba24
parent31758f79db2c9e1122fd40bdda2243311830a5d4
signature Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11467 from ziglang/segmented-list-decls

stage2: use indexes for Decl objects

34 files changed, 3048 insertions(+), 2185 deletions(-)

lib/std/array_hash_map.zig+1-1
...@@ -798,7 +798,7 @@ pub fn ArrayHashMapUnmanaged(...@@ -798,7 +798,7 @@ pub fn ArrayHashMapUnmanaged(
798 allocator: Allocator,798 allocator: Allocator,
799 additional_capacity: usize,799 additional_capacity: usize,
800 ) !void {800 ) !void {
801 if (@sizeOf(ByIndexContext) != 0)801 if (@sizeOf(Context) != 0)
802 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call ensureTotalCapacityContext instead.");802 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call ensureTotalCapacityContext instead.");
803 return self.ensureUnusedCapacityContext(allocator, additional_capacity, undefined);803 return self.ensureUnusedCapacityContext(allocator, additional_capacity, undefined);
804 }804 }
lib/std/hash_map.zig+2
...@@ -913,6 +913,8 @@ pub fn HashMapUnmanaged(...@@ -913,6 +913,8 @@ pub fn HashMapUnmanaged(
913 }913 }
914914
915 pub fn ensureUnusedCapacity(self: *Self, allocator: Allocator, additional_size: Size) Allocator.Error!void {915 pub fn ensureUnusedCapacity(self: *Self, allocator: Allocator, additional_size: Size) Allocator.Error!void {
916 if (@sizeOf(Context) != 0)
917 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call ensureUnusedCapacityContext instead.");
916 return ensureUnusedCapacityContext(self, allocator, additional_size, undefined);918 return ensureUnusedCapacityContext(self, allocator, additional_size, undefined);
917 }919 }
918 pub fn ensureUnusedCapacityContext(self: *Self, allocator: Allocator, additional_size: Size, ctx: Context) Allocator.Error!void {920 pub fn ensureUnusedCapacityContext(self: *Self, allocator: Allocator, additional_size: Size, ctx: Context) Allocator.Error!void {
lib/std/segmented_list.zig created+472
...@@ -0,0 +1,472 @@
1const std = @import("std.zig");
2const assert = std.debug.assert;
3const testing = std.testing;
4const Allocator = std.mem.Allocator;
5
6// Imagine that `fn at(self: *Self, index: usize) &T` is a customer asking for a box
7// from a warehouse, based on a flat array, boxes ordered from 0 to N - 1.
8// But the warehouse actually stores boxes in shelves of increasing powers of 2 sizes.
9// So when the customer requests a box index, we have to translate it to shelf index
10// and box index within that shelf. Illustration:
11//
12// customer indexes:
13// shelf 0: 0
14// shelf 1: 1 2
15// shelf 2: 3 4 5 6
16// shelf 3: 7 8 9 10 11 12 13 14
17// shelf 4: 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
18// shelf 5: 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
19// ...
20//
21// warehouse indexes:
22// shelf 0: 0
23// shelf 1: 0 1
24// shelf 2: 0 1 2 3
25// shelf 3: 0 1 2 3 4 5 6 7
26// shelf 4: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
27// shelf 5: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
28// ...
29//
30// With this arrangement, here are the equations to get the shelf index and
31// box index based on customer box index:
32//
33// shelf_index = floor(log2(customer_index + 1))
34// shelf_count = ceil(log2(box_count + 1))
35// box_index = customer_index + 1 - 2 ** shelf
36// shelf_size = 2 ** shelf_index
37//
38// Now we complicate it a little bit further by adding a preallocated shelf, which must be
39// a power of 2:
40// prealloc=4
41//
42// customer indexes:
43// prealloc: 0 1 2 3
44// shelf 0: 4 5 6 7 8 9 10 11
45// shelf 1: 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
46// shelf 2: 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
47// ...
48//
49// warehouse indexes:
50// prealloc: 0 1 2 3
51// shelf 0: 0 1 2 3 4 5 6 7
52// shelf 1: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
53// shelf 2: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
54// ...
55//
56// Now the equations are:
57//
58// shelf_index = floor(log2(customer_index + prealloc)) - log2(prealloc) - 1
59// shelf_count = ceil(log2(box_count + prealloc)) - log2(prealloc) - 1
60// box_index = customer_index + prealloc - 2 ** (log2(prealloc) + 1 + shelf)
61// shelf_size = prealloc * 2 ** (shelf_index + 1)
62
63/// This is a stack data structure where pointers to indexes have the same lifetime as the data structure
64/// itself, unlike ArrayList where append() invalidates all existing element pointers.
65/// The tradeoff is that elements are not guaranteed to be contiguous. For that, use ArrayList.
66/// Note however that most elements are contiguous, making this data structure cache-friendly.
67///
68/// Because it never has to copy elements from an old location to a new location, it does not require
69/// its elements to be copyable, and it avoids wasting memory when backed by an ArenaAllocator.
70/// Note that the append() and pop() convenience methods perform a copy, but you can instead use
71/// addOne(), at(), setCapacity(), and shrinkCapacity() to avoid copying items.
72///
73/// This data structure has O(1) append and O(1) pop.
74///
75/// It supports preallocated elements, making it especially well suited when the expected maximum
76/// size is small. `prealloc_item_count` must be 0, or a power of 2.
77pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type {
78 return struct {
79 const Self = @This();
80 const ShelfIndex = std.math.Log2Int(usize);
81
82 const prealloc_exp: ShelfIndex = blk: {
83 // we don't use the prealloc_exp constant when prealloc_item_count is 0
84 // but lazy-init may still be triggered by other code so supply a value
85 if (prealloc_item_count == 0) {
86 break :blk 0;
87 } else {
88 assert(std.math.isPowerOfTwo(prealloc_item_count));
89 const value = std.math.log2_int(usize, prealloc_item_count);
90 break :blk value;
91 }
92 };
93
94 prealloc_segment: [prealloc_item_count]T = undefined,
95 dynamic_segments: [][*]T = &[_][*]T{},
96 len: usize = 0,
97
98 pub const prealloc_count = prealloc_item_count;
99
100 fn AtType(comptime SelfType: type) type {
101 if (@typeInfo(SelfType).Pointer.is_const) {
102 return *const T;
103 } else {
104 return *T;
105 }
106 }
107
108 pub fn deinit(self: *Self, allocator: Allocator) void {
109 self.freeShelves(allocator, @intCast(ShelfIndex, self.dynamic_segments.len), 0);
110 allocator.free(self.dynamic_segments);
111 self.* = undefined;
112 }
113
114 pub fn at(self: anytype, i: usize) AtType(@TypeOf(self)) {
115 assert(i < self.len);
116 return self.uncheckedAt(i);
117 }
118
119 pub fn count(self: Self) usize {
120 return self.len;
121 }
122
123 pub fn append(self: *Self, allocator: Allocator, item: T) Allocator.Error!void {
124 const new_item_ptr = try self.addOne(allocator);
125 new_item_ptr.* = item;
126 }
127
128 pub fn appendSlice(self: *Self, allocator: Allocator, items: []const T) Allocator.Error!void {
129 for (items) |item| {
130 try self.append(allocator, item);
131 }
132 }
133
134 pub fn pop(self: *Self) ?T {
135 if (self.len == 0) return null;
136
137 const index = self.len - 1;
138 const result = uncheckedAt(self, index).*;
139 self.len = index;
140 return result;
141 }
142
143 pub fn addOne(self: *Self, allocator: Allocator) Allocator.Error!*T {
144 const new_length = self.len + 1;
145 try self.growCapacity(allocator, new_length);
146 const result = uncheckedAt(self, self.len);
147 self.len = new_length;
148 return result;
149 }
150
151 /// Reduce length to `new_len`.
152 /// Invalidates pointers for the elements at index new_len and beyond.
153 pub fn shrinkRetainingCapacity(self: *Self, new_len: usize) void {
154 assert(new_len <= self.len);
155 self.len = new_len;
156 }
157
158 /// Invalidates all element pointers.
159 pub fn clearRetainingCapacity(self: *Self) void {
160 self.items.len = 0;
161 }
162
163 /// Invalidates all element pointers.
164 pub fn clearAndFree(self: *Self, allocator: Allocator) void {
165 self.setCapacity(allocator, 0) catch unreachable;
166 self.items.len = 0;
167 }
168
169 /// Grows or shrinks capacity to match usage.
170 /// TODO update this and related methods to match the conventions set by ArrayList
171 pub fn setCapacity(self: *Self, allocator: Allocator, new_capacity: usize) Allocator.Error!void {
172 if (prealloc_item_count != 0) {
173 if (new_capacity <= @as(usize, 1) << (prealloc_exp + @intCast(ShelfIndex, self.dynamic_segments.len))) {
174 return self.shrinkCapacity(allocator, new_capacity);
175 }
176 }
177 return self.growCapacity(allocator, new_capacity);
178 }
179
180 /// Only grows capacity, or retains current capacity
181 pub fn growCapacity(self: *Self, allocator: Allocator, new_capacity: usize) Allocator.Error!void {
182 const new_cap_shelf_count = shelfCount(new_capacity);
183 const old_shelf_count = @intCast(ShelfIndex, self.dynamic_segments.len);
184 if (new_cap_shelf_count > old_shelf_count) {
185 self.dynamic_segments = try allocator.realloc(self.dynamic_segments, new_cap_shelf_count);
186 var i = old_shelf_count;
187 errdefer {
188 self.freeShelves(allocator, i, old_shelf_count);
189 self.dynamic_segments = allocator.shrink(self.dynamic_segments, old_shelf_count);
190 }
191 while (i < new_cap_shelf_count) : (i += 1) {
192 self.dynamic_segments[i] = (try allocator.alloc(T, shelfSize(i))).ptr;
193 }
194 }
195 }
196
197 /// Only shrinks capacity or retains current capacity
198 pub fn shrinkCapacity(self: *Self, allocator: Allocator, new_capacity: usize) void {
199 if (new_capacity <= prealloc_item_count) {
200 const len = @intCast(ShelfIndex, self.dynamic_segments.len);
201 self.freeShelves(allocator, len, 0);
202 allocator.free(self.dynamic_segments);
203 self.dynamic_segments = &[_][*]T{};
204 return;
205 }
206
207 const new_cap_shelf_count = shelfCount(new_capacity);
208 const old_shelf_count = @intCast(ShelfIndex, self.dynamic_segments.len);
209 assert(new_cap_shelf_count <= old_shelf_count);
210 if (new_cap_shelf_count == old_shelf_count) {
211 return;
212 }
213
214 self.freeShelves(allocator, old_shelf_count, new_cap_shelf_count);
215 self.dynamic_segments = allocator.shrink(self.dynamic_segments, new_cap_shelf_count);
216 }
217
218 pub fn shrink(self: *Self, new_len: usize) void {
219 assert(new_len <= self.len);
220 // TODO take advantage of the new realloc semantics
221 self.len = new_len;
222 }
223
224 pub fn writeToSlice(self: *Self, dest: []T, start: usize) void {
225 const end = start + dest.len;
226 assert(end <= self.len);
227
228 var i = start;
229 if (end <= prealloc_item_count) {
230 std.mem.copy(T, dest[i - start ..], self.prealloc_segment[i..end]);
231 return;
232 } else if (i < prealloc_item_count) {
233 std.mem.copy(T, dest[i - start ..], self.prealloc_segment[i..]);
234 i = prealloc_item_count;
235 }
236
237 while (i < end) {
238 const shelf_index = shelfIndex(i);
239 const copy_start = boxIndex(i, shelf_index);
240 const copy_end = std.math.min(shelfSize(shelf_index), copy_start + end - i);
241
242 std.mem.copy(
243 T,
244 dest[i - start ..],
245 self.dynamic_segments[shelf_index][copy_start..copy_end],
246 );
247
248 i += (copy_end - copy_start);
249 }
250 }
251
252 pub fn uncheckedAt(self: anytype, index: usize) AtType(@TypeOf(self)) {
253 if (index < prealloc_item_count) {
254 return &self.prealloc_segment[index];
255 }
256 const shelf_index = shelfIndex(index);
257 const box_index = boxIndex(index, shelf_index);
258 return &self.dynamic_segments[shelf_index][box_index];
259 }
260
261 fn shelfCount(box_count: usize) ShelfIndex {
262 if (prealloc_item_count == 0) {
263 return log2_int_ceil(usize, box_count + 1);
264 }
265 return log2_int_ceil(usize, box_count + prealloc_item_count) - prealloc_exp - 1;
266 }
267
268 fn shelfSize(shelf_index: ShelfIndex) usize {
269 if (prealloc_item_count == 0) {
270 return @as(usize, 1) << shelf_index;
271 }
272 return @as(usize, 1) << (shelf_index + (prealloc_exp + 1));
273 }
274
275 fn shelfIndex(list_index: usize) ShelfIndex {
276 if (prealloc_item_count == 0) {
277 return std.math.log2_int(usize, list_index + 1);
278 }
279 return std.math.log2_int(usize, list_index + prealloc_item_count) - prealloc_exp - 1;
280 }
281
282 fn boxIndex(list_index: usize, shelf_index: ShelfIndex) usize {
283 if (prealloc_item_count == 0) {
284 return (list_index + 1) - (@as(usize, 1) << shelf_index);
285 }
286 return list_index + prealloc_item_count - (@as(usize, 1) << ((prealloc_exp + 1) + shelf_index));
287 }
288
289 fn freeShelves(self: *Self, allocator: Allocator, from_count: ShelfIndex, to_count: ShelfIndex) void {
290 var i = from_count;
291 while (i != to_count) {
292 i -= 1;
293 allocator.free(self.dynamic_segments[i][0..shelfSize(i)]);
294 }
295 }
296
297 pub const Iterator = struct {
298 list: *Self,
299 index: usize,
300 box_index: usize,
301 shelf_index: ShelfIndex,
302 shelf_size: usize,
303
304 pub fn next(it: *Iterator) ?*T {
305 if (it.index >= it.list.len) return null;
306 if (it.index < prealloc_item_count) {
307 const ptr = &it.list.prealloc_segment[it.index];
308 it.index += 1;
309 if (it.index == prealloc_item_count) {
310 it.box_index = 0;
311 it.shelf_index = 0;
312 it.shelf_size = prealloc_item_count * 2;
313 }
314 return ptr;
315 }
316
317 const ptr = &it.list.dynamic_segments[it.shelf_index][it.box_index];
318 it.index += 1;
319 it.box_index += 1;
320 if (it.box_index == it.shelf_size) {
321 it.shelf_index += 1;
322 it.box_index = 0;
323 it.shelf_size *= 2;
324 }
325 return ptr;
326 }
327
328 pub fn prev(it: *Iterator) ?*T {
329 if (it.index == 0) return null;
330
331 it.index -= 1;
332 if (it.index < prealloc_item_count) return &it.list.prealloc_segment[it.index];
333
334 if (it.box_index == 0) {
335 it.shelf_index -= 1;
336 it.shelf_size /= 2;
337 it.box_index = it.shelf_size - 1;
338 } else {
339 it.box_index -= 1;
340 }
341
342 return &it.list.dynamic_segments[it.shelf_index][it.box_index];
343 }
344
345 pub fn peek(it: *Iterator) ?*T {
346 if (it.index >= it.list.len)
347 return null;
348 if (it.index < prealloc_item_count)
349 return &it.list.prealloc_segment[it.index];
350
351 return &it.list.dynamic_segments[it.shelf_index][it.box_index];
352 }
353
354 pub fn set(it: *Iterator, index: usize) void {
355 it.index = index;
356 if (index < prealloc_item_count) return;
357 it.shelf_index = shelfIndex(index);
358 it.box_index = boxIndex(index, it.shelf_index);
359 it.shelf_size = shelfSize(it.shelf_index);
360 }
361 };
362
363 pub fn iterator(self: *Self, start_index: usize) Iterator {
364 var it = Iterator{
365 .list = self,
366 .index = undefined,
367 .shelf_index = undefined,
368 .box_index = undefined,
369 .shelf_size = undefined,
370 };
371 it.set(start_index);
372 return it;
373 }
374 };
375}
376
377test "basic usage" {
378 try testSegmentedList(0);
379 try testSegmentedList(1);
380 try testSegmentedList(2);
381 try testSegmentedList(4);
382 try testSegmentedList(8);
383 try testSegmentedList(16);
384}
385
386fn testSegmentedList(comptime prealloc: usize) !void {
387 const gpa = std.testing.allocator;
388
389 var list: SegmentedList(i32, prealloc) = .{};
390 defer list.deinit(gpa);
391
392 {
393 var i: usize = 0;
394 while (i < 100) : (i += 1) {
395 try list.append(gpa, @intCast(i32, i + 1));
396 try testing.expect(list.len == i + 1);
397 }
398 }
399
400 {
401 var i: usize = 0;
402 while (i < 100) : (i += 1) {
403 try testing.expect(list.at(i).* == @intCast(i32, i + 1));
404 }
405 }
406
407 {
408 var it = list.iterator(0);
409 var x: i32 = 0;
410 while (it.next()) |item| {
411 x += 1;
412 try testing.expect(item.* == x);
413 }
414 try testing.expect(x == 100);
415 while (it.prev()) |item| : (x -= 1) {
416 try testing.expect(item.* == x);
417 }
418 try testing.expect(x == 0);
419 }
420
421 try testing.expect(list.pop().? == 100);
422 try testing.expect(list.len == 99);
423
424 try list.appendSlice(gpa, &[_]i32{ 1, 2, 3 });
425 try testing.expect(list.len == 102);
426 try testing.expect(list.pop().? == 3);
427 try testing.expect(list.pop().? == 2);
428 try testing.expect(list.pop().? == 1);
429 try testing.expect(list.len == 99);
430
431 try list.appendSlice(gpa, &[_]i32{});
432 try testing.expect(list.len == 99);
433
434 {
435 var i: i32 = 99;
436 while (list.pop()) |item| : (i -= 1) {
437 try testing.expect(item == i);
438 list.shrinkCapacity(gpa, list.len);
439 }
440 }
441
442 {
443 var control: [100]i32 = undefined;
444 var dest: [100]i32 = undefined;
445
446 var i: i32 = 0;
447 while (i < 100) : (i += 1) {
448 try list.append(gpa, i + 1);
449 control[@intCast(usize, i)] = i + 1;
450 }
451
452 std.mem.set(i32, dest[0..], 0);
453 list.writeToSlice(dest[0..], 0);
454 try testing.expect(std.mem.eql(i32, control[0..], dest[0..]));
455
456 std.mem.set(i32, dest[0..], 0);
457 list.writeToSlice(dest[50..], 50);
458 try testing.expect(std.mem.eql(i32, control[50..], dest[50..]));
459 }
460
461 try list.setCapacity(gpa, 0);
462}
463
464/// TODO look into why this std.math function was changed in
465/// fc9430f56798a53f9393a697f4ccd6bf9981b970.
466fn log2_int_ceil(comptime T: type, x: T) std.math.Log2Int(T) {
467 assert(x != 0);
468 const log2_val = std.math.log2_int(T, x);
469 if (@as(T, 1) << log2_val == x)
470 return log2_val;
471 return log2_val + 1;
472}
lib/std/std.zig+1
...@@ -29,6 +29,7 @@ pub const PackedIntSliceEndian = @import("packed_int_array.zig").PackedIntSliceE...@@ -29,6 +29,7 @@ pub const PackedIntSliceEndian = @import("packed_int_array.zig").PackedIntSliceE
29pub const PriorityQueue = @import("priority_queue.zig").PriorityQueue;29pub const PriorityQueue = @import("priority_queue.zig").PriorityQueue;
30pub const PriorityDequeue = @import("priority_dequeue.zig").PriorityDequeue;30pub const PriorityDequeue = @import("priority_dequeue.zig").PriorityDequeue;
31pub const Progress = @import("Progress.zig");31pub const Progress = @import("Progress.zig");
32pub const SegmentedList = @import("segmented_list.zig").SegmentedList;
32pub const SemanticVersion = @import("SemanticVersion.zig");33pub const SemanticVersion = @import("SemanticVersion.zig");
33pub const SinglyLinkedList = @import("linked_list.zig").SinglyLinkedList;34pub const SinglyLinkedList = @import("linked_list.zig").SinglyLinkedList;
34pub const StaticBitSet = bit_set.StaticBitSet;35pub const StaticBitSet = bit_set.StaticBitSet;
src/Compilation.zig+120-103
...@@ -191,22 +191,22 @@ pub const CSourceFile = struct {...@@ -191,22 +191,22 @@ pub const CSourceFile = struct {
191191
192const Job = union(enum) {192const Job = union(enum) {
193 /// Write the constant value for a Decl to the output file.193 /// Write the constant value for a Decl to the output file.
194 codegen_decl: *Module.Decl,194 codegen_decl: Module.Decl.Index,
195 /// Write the machine code for a function to the output file.195 /// Write the machine code for a function to the output file.
196 codegen_func: *Module.Fn,196 codegen_func: *Module.Fn,
197 /// Render the .h file snippet for the Decl.197 /// Render the .h file snippet for the Decl.
198 emit_h_decl: *Module.Decl,198 emit_h_decl: Module.Decl.Index,
199 /// The Decl needs to be analyzed and possibly export itself.199 /// The Decl needs to be analyzed and possibly export itself.
200 /// It may have already be analyzed, or it may have been determined200 /// It may have already be analyzed, or it may have been determined
201 /// to be outdated; in this case perform semantic analysis again.201 /// to be outdated; in this case perform semantic analysis again.
202 analyze_decl: *Module.Decl,202 analyze_decl: Module.Decl.Index,
203 /// The file that was loaded with `@embedFile` has changed on disk203 /// The file that was loaded with `@embedFile` has changed on disk
204 /// and has been re-loaded into memory. All Decls that depend on it204 /// and has been re-loaded into memory. All Decls that depend on it
205 /// need to be re-analyzed.205 /// need to be re-analyzed.
206 update_embed_file: *Module.EmbedFile,206 update_embed_file: *Module.EmbedFile,
207 /// The source file containing the Decl has been updated, and so the207 /// The source file containing the Decl has been updated, and so the
208 /// Decl may need its line number information updated in the debug info.208 /// Decl may need its line number information updated in the debug info.
209 update_line_number: *Module.Decl,209 update_line_number: Module.Decl.Index,
210 /// The main source file for the package needs to be analyzed.210 /// The main source file for the package needs to be analyzed.
211 analyze_pkg: *Package,211 analyze_pkg: *Package,
212212
...@@ -2105,17 +2105,18 @@ pub fn update(comp: *Compilation) !void {...@@ -2105,17 +2105,18 @@ pub fn update(comp: *Compilation) !void {
2105 // deletion set may grow as we call `clearDecl` within this loop,2105 // deletion set may grow as we call `clearDecl` within this loop,
2106 // and more unreferenced Decls are revealed.2106 // and more unreferenced Decls are revealed.
2107 while (module.deletion_set.count() != 0) {2107 while (module.deletion_set.count() != 0) {
2108 const decl = module.deletion_set.keys()[0];2108 const decl_index = module.deletion_set.keys()[0];
2109 const decl = module.declPtr(decl_index);
2109 assert(decl.deletion_flag);2110 assert(decl.deletion_flag);
2110 assert(decl.dependants.count() == 0);2111 assert(decl.dependants.count() == 0);
2111 const is_anon = if (decl.zir_decl_index == 0) blk: {2112 const is_anon = if (decl.zir_decl_index == 0) blk: {
2112 break :blk decl.src_namespace.anon_decls.swapRemove(decl);2113 break :blk decl.src_namespace.anon_decls.swapRemove(decl_index);
2113 } else false;2114 } else false;
21142115
2115 try module.clearDecl(decl, null);2116 try module.clearDecl(decl_index, null);
21162117
2117 if (is_anon) {2118 if (is_anon) {
2118 decl.destroy(module);2119 module.destroyDecl(decl_index);
2119 }2120 }
2120 }2121 }
21212122
...@@ -2444,13 +2445,15 @@ pub fn totalErrorCount(self: *Compilation) usize {...@@ -2444,13 +2445,15 @@ pub fn totalErrorCount(self: *Compilation) usize {
2444 // the previous parse success, including compile errors, but we cannot2445 // the previous parse success, including compile errors, but we cannot
2445 // emit them until the file succeeds parsing.2446 // emit them until the file succeeds parsing.
2446 for (module.failed_decls.keys()) |key| {2447 for (module.failed_decls.keys()) |key| {
2447 if (key.getFileScope().okToReportErrors()) {2448 const decl = module.declPtr(key);
2449 if (decl.getFileScope().okToReportErrors()) {
2448 total += 1;2450 total += 1;
2449 }2451 }
2450 }2452 }
2451 if (module.emit_h) |emit_h| {2453 if (module.emit_h) |emit_h| {
2452 for (emit_h.failed_decls.keys()) |key| {2454 for (emit_h.failed_decls.keys()) |key| {
2453 if (key.getFileScope().okToReportErrors()) {2455 const decl = module.declPtr(key);
2456 if (decl.getFileScope().okToReportErrors()) {
2454 total += 1;2457 total += 1;
2455 }2458 }
2456 }2459 }
...@@ -2529,9 +2532,10 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {...@@ -2529,9 +2532,10 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
2529 {2532 {
2530 var it = module.failed_decls.iterator();2533 var it = module.failed_decls.iterator();
2531 while (it.next()) |entry| {2534 while (it.next()) |entry| {
2535 const decl = module.declPtr(entry.key_ptr.*);
2532 // Skip errors for Decls within files that had a parse failure.2536 // Skip errors for Decls within files that had a parse failure.
2533 // We'll try again once parsing succeeds.2537 // We'll try again once parsing succeeds.
2534 if (entry.key_ptr.*.getFileScope().okToReportErrors()) {2538 if (decl.getFileScope().okToReportErrors()) {
2535 try AllErrors.add(module, &arena, &errors, entry.value_ptr.*.*);2539 try AllErrors.add(module, &arena, &errors, entry.value_ptr.*.*);
2536 }2540 }
2537 }2541 }
...@@ -2539,9 +2543,10 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {...@@ -2539,9 +2543,10 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
2539 if (module.emit_h) |emit_h| {2543 if (module.emit_h) |emit_h| {
2540 var it = emit_h.failed_decls.iterator();2544 var it = emit_h.failed_decls.iterator();
2541 while (it.next()) |entry| {2545 while (it.next()) |entry| {
2546 const decl = module.declPtr(entry.key_ptr.*);
2542 // Skip errors for Decls within files that had a parse failure.2547 // Skip errors for Decls within files that had a parse failure.
2543 // We'll try again once parsing succeeds.2548 // We'll try again once parsing succeeds.
2544 if (entry.key_ptr.*.getFileScope().okToReportErrors()) {2549 if (decl.getFileScope().okToReportErrors()) {
2545 try AllErrors.add(module, &arena, &errors, entry.value_ptr.*.*);2550 try AllErrors.add(module, &arena, &errors, entry.value_ptr.*.*);
2546 }2551 }
2547 }2552 }
...@@ -2564,7 +2569,8 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {...@@ -2564,7 +2569,8 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
2564 const keys = module.compile_log_decls.keys();2569 const keys = module.compile_log_decls.keys();
2565 const values = module.compile_log_decls.values();2570 const values = module.compile_log_decls.values();
2566 // First one will be the error; subsequent ones will be notes.2571 // First one will be the error; subsequent ones will be notes.
2567 const src_loc = keys[0].nodeOffsetSrcLoc(values[0]);2572 const err_decl = module.declPtr(keys[0]);
2573 const src_loc = err_decl.nodeOffsetSrcLoc(values[0]);
2568 const err_msg = Module.ErrorMsg{2574 const err_msg = Module.ErrorMsg{
2569 .src_loc = src_loc,2575 .src_loc = src_loc,
2570 .msg = "found compile log statement",2576 .msg = "found compile log statement",
...@@ -2573,8 +2579,9 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {...@@ -2573,8 +2579,9 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
2573 defer self.gpa.free(err_msg.notes);2579 defer self.gpa.free(err_msg.notes);
25742580
2575 for (keys[1..]) |key, i| {2581 for (keys[1..]) |key, i| {
2582 const note_decl = module.declPtr(key);
2576 err_msg.notes[i] = .{2583 err_msg.notes[i] = .{
2577 .src_loc = key.nodeOffsetSrcLoc(values[i + 1]),2584 .src_loc = note_decl.nodeOffsetSrcLoc(values[i + 1]),
2578 .msg = "also here",2585 .msg = "also here",
2579 };2586 };
2580 }2587 }
...@@ -2708,38 +2715,42 @@ pub fn performAllTheWork(...@@ -2708,38 +2715,42 @@ pub fn performAllTheWork(
27082715
2709fn processOneJob(comp: *Compilation, job: Job) !void {2716fn processOneJob(comp: *Compilation, job: Job) !void {
2710 switch (job) {2717 switch (job) {
2711 .codegen_decl => |decl| switch (decl.analysis) {2718 .codegen_decl => |decl_index| {
2712 .unreferenced => unreachable,2719 if (build_options.omit_stage2)
2713 .in_progress => unreachable,2720 @panic("sadly stage2 is omitted from this build to save memory on the CI server");
2714 .outdated => unreachable,
2715
2716 .file_failure,
2717 .sema_failure,
2718 .codegen_failure,
2719 .dependency_failure,
2720 .sema_failure_retryable,
2721 => return,
2722
2723 .complete, .codegen_failure_retryable => {
2724 if (build_options.omit_stage2)
2725 @panic("sadly stage2 is omitted from this build to save memory on the CI server");
2726
2727 const named_frame = tracy.namedFrame("codegen_decl");
2728 defer named_frame.end();
2729
2730 const module = comp.bin_file.options.module.?;
2731 assert(decl.has_tv);
2732
2733 if (decl.alive) {
2734 try module.linkerUpdateDecl(decl);
2735 return;
2736 }
27372721
2738 // Instead of sending this decl to the linker, we actually will delete it2722 const module = comp.bin_file.options.module.?;
2739 // because we found out that it in fact was never referenced.2723 const decl = module.declPtr(decl_index);
2740 module.deleteUnusedDecl(decl);2724
2741 return;2725 switch (decl.analysis) {
2742 },2726 .unreferenced => unreachable,
2727 .in_progress => unreachable,
2728 .outdated => unreachable,
2729
2730 .file_failure,
2731 .sema_failure,
2732 .codegen_failure,
2733 .dependency_failure,
2734 .sema_failure_retryable,
2735 => return,
2736
2737 .complete, .codegen_failure_retryable => {
2738 const named_frame = tracy.namedFrame("codegen_decl");
2739 defer named_frame.end();
2740
2741 assert(decl.has_tv);
2742
2743 if (decl.alive) {
2744 try module.linkerUpdateDecl(decl_index);
2745 return;
2746 }
2747
2748 // Instead of sending this decl to the linker, we actually will delete it
2749 // because we found out that it in fact was never referenced.
2750 module.deleteUnusedDecl(decl_index);
2751 return;
2752 },
2753 }
2743 },2754 },
2744 .codegen_func => |func| {2755 .codegen_func => |func| {
2745 if (build_options.omit_stage2)2756 if (build_options.omit_stage2)
...@@ -2754,68 +2765,73 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -2754,68 +2765,73 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
2754 error.AnalysisFail => return,2765 error.AnalysisFail => return,
2755 };2766 };
2756 },2767 },
2757 .emit_h_decl => |decl| switch (decl.analysis) {2768 .emit_h_decl => |decl_index| {
2758 .unreferenced => unreachable,2769 if (build_options.omit_stage2)
2759 .in_progress => unreachable,2770 @panic("sadly stage2 is omitted from this build to save memory on the CI server");
2760 .outdated => unreachable,
2761
2762 .file_failure,
2763 .sema_failure,
2764 .dependency_failure,
2765 .sema_failure_retryable,
2766 => return,
2767
2768 // emit-h only requires semantic analysis of the Decl to be complete,
2769 // it does not depend on machine code generation to succeed.
2770 .codegen_failure, .codegen_failure_retryable, .complete => {
2771 if (build_options.omit_stage2)
2772 @panic("sadly stage2 is omitted from this build to save memory on the CI server");
2773
2774 const named_frame = tracy.namedFrame("emit_h_decl");
2775 defer named_frame.end();
2776
2777 const gpa = comp.gpa;
2778 const module = comp.bin_file.options.module.?;
2779 const emit_h = module.emit_h.?;
2780 _ = try emit_h.decl_table.getOrPut(gpa, decl);
2781 const decl_emit_h = decl.getEmitH(module);
2782 const fwd_decl = &decl_emit_h.fwd_decl;
2783 fwd_decl.shrinkRetainingCapacity(0);
2784 var typedefs_arena = std.heap.ArenaAllocator.init(gpa);
2785 defer typedefs_arena.deinit();
2786
2787 var dg: c_codegen.DeclGen = .{
2788 .gpa = gpa,
2789 .module = module,
2790 .error_msg = null,
2791 .decl = decl,
2792 .fwd_decl = fwd_decl.toManaged(gpa),
2793 .typedefs = c_codegen.TypedefMap.initContext(gpa, .{
2794 .target = comp.getTarget(),
2795 }),
2796 .typedefs_arena = typedefs_arena.allocator(),
2797 };
2798 defer dg.fwd_decl.deinit();
2799 defer dg.typedefs.deinit();
28002771
2801 c_codegen.genHeader(&dg) catch |err| switch (err) {2772 const module = comp.bin_file.options.module.?;
2802 error.AnalysisFail => {2773 const decl = module.declPtr(decl_index);
2803 try emit_h.failed_decls.put(gpa, decl, dg.error_msg.?);2774
2804 return;2775 switch (decl.analysis) {
2805 },2776 .unreferenced => unreachable,
2806 else => |e| return e,2777 .in_progress => unreachable,
2807 };2778 .outdated => unreachable,
2779
2780 .file_failure,
2781 .sema_failure,
2782 .dependency_failure,
2783 .sema_failure_retryable,
2784 => return,
2785
2786 // emit-h only requires semantic analysis of the Decl to be complete,
2787 // it does not depend on machine code generation to succeed.
2788 .codegen_failure, .codegen_failure_retryable, .complete => {
2789 const named_frame = tracy.namedFrame("emit_h_decl");
2790 defer named_frame.end();
2791
2792 const gpa = comp.gpa;
2793 const emit_h = module.emit_h.?;
2794 _ = try emit_h.decl_table.getOrPut(gpa, decl_index);
2795 const decl_emit_h = emit_h.declPtr(decl_index);
2796 const fwd_decl = &decl_emit_h.fwd_decl;
2797 fwd_decl.shrinkRetainingCapacity(0);
2798 var typedefs_arena = std.heap.ArenaAllocator.init(gpa);
2799 defer typedefs_arena.deinit();
2800
2801 var dg: c_codegen.DeclGen = .{
2802 .gpa = gpa,
2803 .module = module,
2804 .error_msg = null,
2805 .decl_index = decl_index,
2806 .decl = decl,
2807 .fwd_decl = fwd_decl.toManaged(gpa),
2808 .typedefs = c_codegen.TypedefMap.initContext(gpa, .{
2809 .mod = module,
2810 }),
2811 .typedefs_arena = typedefs_arena.allocator(),
2812 };
2813 defer dg.fwd_decl.deinit();
2814 defer dg.typedefs.deinit();
28082815
2809 fwd_decl.* = dg.fwd_decl.moveToUnmanaged();2816 c_codegen.genHeader(&dg) catch |err| switch (err) {
2810 fwd_decl.shrinkAndFree(gpa, fwd_decl.items.len);2817 error.AnalysisFail => {
2811 },2818 try emit_h.failed_decls.put(gpa, decl_index, dg.error_msg.?);
2819 return;
2820 },
2821 else => |e| return e,
2822 };
2823
2824 fwd_decl.* = dg.fwd_decl.moveToUnmanaged();
2825 fwd_decl.shrinkAndFree(gpa, fwd_decl.items.len);
2826 },
2827 }
2812 },2828 },
2813 .analyze_decl => |decl| {2829 .analyze_decl => |decl_index| {
2814 if (build_options.omit_stage2)2830 if (build_options.omit_stage2)
2815 @panic("sadly stage2 is omitted from this build to save memory on the CI server");2831 @panic("sadly stage2 is omitted from this build to save memory on the CI server");
28162832
2817 const module = comp.bin_file.options.module.?;2833 const module = comp.bin_file.options.module.?;
2818 module.ensureDeclAnalyzed(decl) catch |err| switch (err) {2834 module.ensureDeclAnalyzed(decl_index) catch |err| switch (err) {
2819 error.OutOfMemory => return error.OutOfMemory,2835 error.OutOfMemory => return error.OutOfMemory,
2820 error.AnalysisFail => return,2836 error.AnalysisFail => return,
2821 };2837 };
...@@ -2833,7 +2849,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -2833,7 +2849,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
2833 error.AnalysisFail => return,2849 error.AnalysisFail => return,
2834 };2850 };
2835 },2851 },
2836 .update_line_number => |decl| {2852 .update_line_number => |decl_index| {
2837 if (build_options.omit_stage2)2853 if (build_options.omit_stage2)
2838 @panic("sadly stage2 is omitted from this build to save memory on the CI server");2854 @panic("sadly stage2 is omitted from this build to save memory on the CI server");
28392855
...@@ -2842,9 +2858,10 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -2842,9 +2858,10 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
28422858
2843 const gpa = comp.gpa;2859 const gpa = comp.gpa;
2844 const module = comp.bin_file.options.module.?;2860 const module = comp.bin_file.options.module.?;
2861 const decl = module.declPtr(decl_index);
2845 comp.bin_file.updateDeclLineNumber(module, decl) catch |err| {2862 comp.bin_file.updateDeclLineNumber(module, decl) catch |err| {
2846 try module.failed_decls.ensureUnusedCapacity(gpa, 1);2863 try module.failed_decls.ensureUnusedCapacity(gpa, 1);
2847 module.failed_decls.putAssumeCapacityNoClobber(decl, try Module.ErrorMsg.create(2864 module.failed_decls.putAssumeCapacityNoClobber(decl_index, try Module.ErrorMsg.create(
2848 gpa,2865 gpa,
2849 decl.srcLoc(),2866 decl.srcLoc(),
2850 "unable to update line number: {s}",2867 "unable to update line number: {s}",
...@@ -3472,7 +3489,7 @@ fn reportRetryableEmbedFileError(...@@ -3472,7 +3489,7 @@ fn reportRetryableEmbedFileError(
3472 const mod = comp.bin_file.options.module.?;3489 const mod = comp.bin_file.options.module.?;
3473 const gpa = mod.gpa;3490 const gpa = mod.gpa;
34743491
3475 const src_loc: Module.SrcLoc = embed_file.owner_decl.srcLoc();3492 const src_loc: Module.SrcLoc = mod.declPtr(embed_file.owner_decl).srcLoc();
34763493
3477 const err_msg = if (embed_file.pkg.root_src_directory.path) |dir_path|3494 const err_msg = if (embed_file.pkg.root_src_directory.path) |dir_path|
3478 try Module.ErrorMsg.create(3495 try Module.ErrorMsg.create(
src/Module.zig+529-381
...@@ -49,15 +49,15 @@ global_zir_cache: Compilation.Directory,...@@ -49,15 +49,15 @@ global_zir_cache: Compilation.Directory,
49/// Used by AstGen worker to load and store ZIR cache.49/// Used by AstGen worker to load and store ZIR cache.
50local_zir_cache: Compilation.Directory,50local_zir_cache: Compilation.Directory,
51/// It's rare for a decl to be exported, so we save memory by having a sparse51/// It's rare for a decl to be exported, so we save memory by having a sparse
52/// map of Decl pointers to details about them being exported.52/// map of Decl indexes to details about them being exported.
53/// The Export memory is owned by the `export_owners` table; the slice itself53/// The Export memory is owned by the `export_owners` table; the slice itself
54/// is owned by this table. The slice is guaranteed to not be empty.54/// is owned by this table. The slice is guaranteed to not be empty.
55decl_exports: std.AutoArrayHashMapUnmanaged(*Decl, []*Export) = .{},55decl_exports: std.AutoArrayHashMapUnmanaged(Decl.Index, []*Export) = .{},
56/// This models the Decls that perform exports, so that `decl_exports` can be updated when a Decl56/// This models the Decls that perform exports, so that `decl_exports` can be updated when a Decl
57/// is modified. Note that the key of this table is not the Decl being exported, but the Decl that57/// is modified. Note that the key of this table is not the Decl being exported, but the Decl that
58/// is performing the export of another Decl.58/// is performing the export of another Decl.
59/// This table owns the Export memory.59/// This table owns the Export memory.
60export_owners: std.AutoArrayHashMapUnmanaged(*Decl, []*Export) = .{},60export_owners: std.AutoArrayHashMapUnmanaged(Decl.Index, []*Export) = .{},
61/// The set of all the Zig source files in the Module. We keep track of this in order61/// The set of all the Zig source files in the Module. We keep track of this in order
62/// to iterate over it and check which source files have been modified on the file system when62/// to iterate over it and check which source files have been modified on the file system when
63/// an update is requested, as well as to cache `@import` results.63/// an update is requested, as well as to cache `@import` results.
...@@ -89,10 +89,10 @@ align_stack_fns: std.AutoHashMapUnmanaged(*const Fn, SetAlignStack) = .{},...@@ -89,10 +89,10 @@ align_stack_fns: std.AutoHashMapUnmanaged(*const Fn, SetAlignStack) = .{},
89/// The ErrorMsg memory is owned by the decl, using Module's general purpose allocator.89/// The ErrorMsg memory is owned by the decl, using Module's general purpose allocator.
90/// Note that a Decl can succeed but the Fn it represents can fail. In this case,90/// Note that a Decl can succeed but the Fn it represents can fail. In this case,
91/// a Decl can have a failed_decls entry but have analysis status of success.91/// a Decl can have a failed_decls entry but have analysis status of success.
92failed_decls: std.AutoArrayHashMapUnmanaged(*Decl, *ErrorMsg) = .{},92failed_decls: std.AutoArrayHashMapUnmanaged(Decl.Index, *ErrorMsg) = .{},
93/// Keep track of one `@compileLog` callsite per owner Decl.93/// Keep track of one `@compileLog` callsite per owner Decl.
94/// The value is the AST node index offset from the Decl.94/// The value is the AST node index offset from the Decl.
95compile_log_decls: std.AutoArrayHashMapUnmanaged(*Decl, i32) = .{},95compile_log_decls: std.AutoArrayHashMapUnmanaged(Decl.Index, i32) = .{},
96/// Using a map here for consistency with the other fields here.96/// Using a map here for consistency with the other fields here.
97/// The ErrorMsg memory is owned by the `File`, using Module's general purpose allocator.97/// The ErrorMsg memory is owned by the `File`, using Module's general purpose allocator.
98failed_files: std.AutoArrayHashMapUnmanaged(*File, ?*ErrorMsg) = .{},98failed_files: std.AutoArrayHashMapUnmanaged(*File, ?*ErrorMsg) = .{},
...@@ -102,11 +102,9 @@ failed_embed_files: std.AutoArrayHashMapUnmanaged(*EmbedFile, *ErrorMsg) = .{},...@@ -102,11 +102,9 @@ failed_embed_files: std.AutoArrayHashMapUnmanaged(*EmbedFile, *ErrorMsg) = .{},
102/// The ErrorMsg memory is owned by the `Export`, using Module's general purpose allocator.102/// The ErrorMsg memory is owned by the `Export`, using Module's general purpose allocator.
103failed_exports: std.AutoArrayHashMapUnmanaged(*Export, *ErrorMsg) = .{},103failed_exports: std.AutoArrayHashMapUnmanaged(*Export, *ErrorMsg) = .{},
104104
105next_anon_name_index: usize = 0,
106
107/// Candidates for deletion. After a semantic analysis update completes, this list105/// Candidates for deletion. After a semantic analysis update completes, this list
108/// contains Decls that need to be deleted if they end up having no references to them.106/// contains Decls that need to be deleted if they end up having no references to them.
109deletion_set: std.AutoArrayHashMapUnmanaged(*Decl, void) = .{},107deletion_set: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{},
110108
111/// Error tags and their values, tag names are duped with mod.gpa.109/// Error tags and their values, tag names are duped with mod.gpa.
112/// Corresponds with `error_name_list`.110/// Corresponds with `error_name_list`.
...@@ -137,7 +135,21 @@ compile_log_text: ArrayListUnmanaged(u8) = .{},...@@ -137,7 +135,21 @@ compile_log_text: ArrayListUnmanaged(u8) = .{},
137135
138emit_h: ?*GlobalEmitH,136emit_h: ?*GlobalEmitH,
139137
140test_functions: std.AutoArrayHashMapUnmanaged(*Decl, void) = .{},138test_functions: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{},
139
140/// Rather than allocating Decl objects with an Allocator, we instead allocate
141/// them with this SegmentedList. This provides four advantages:
142/// * Stable memory so that one thread can access a Decl object while another
143/// thread allocates additional Decl objects from this list.
144/// * It allows us to use u32 indexes to reference Decl objects rather than
145/// pointers, saving memory in Type, Value, and dependency sets.
146/// * Using integers to reference Decl objects rather than pointers makes
147/// serialization trivial.
148/// * It provides a unique integer to be used for anonymous symbol names, avoiding
149/// multi-threaded contention on an atomic counter.
150allocated_decls: std.SegmentedList(Decl, 0) = .{},
151/// When a Decl object is freed from `allocated_decls`, it is pushed into this stack.
152decls_free_list: std.ArrayListUnmanaged(Decl.Index) = .{},
141153
142const MonomorphedFuncsSet = std.HashMapUnmanaged(154const MonomorphedFuncsSet = std.HashMapUnmanaged(
143 *Fn,155 *Fn,
...@@ -173,7 +185,7 @@ pub const MemoizedCallSet = std.HashMapUnmanaged(...@@ -173,7 +185,7 @@ pub const MemoizedCallSet = std.HashMapUnmanaged(
173);185);
174186
175pub const MemoizedCall = struct {187pub const MemoizedCall = struct {
176 target: std.Target,188 module: *Module,
177189
178 pub const Key = struct {190 pub const Key = struct {
179 func: *Fn,191 func: *Fn,
...@@ -191,7 +203,7 @@ pub const MemoizedCall = struct {...@@ -191,7 +203,7 @@ pub const MemoizedCall = struct {
191 assert(a.args.len == b.args.len);203 assert(a.args.len == b.args.len);
192 for (a.args) |a_arg, arg_i| {204 for (a.args) |a_arg, arg_i| {
193 const b_arg = b.args[arg_i];205 const b_arg = b.args[arg_i];
194 if (!a_arg.eql(b_arg, ctx.target)) {206 if (!a_arg.eql(b_arg, ctx.module)) {
195 return false;207 return false;
196 }208 }
197 }209 }
...@@ -210,7 +222,7 @@ pub const MemoizedCall = struct {...@@ -210,7 +222,7 @@ pub const MemoizedCall = struct {
210 // This logic must be kept in sync with the logic in `analyzeCall` that222 // This logic must be kept in sync with the logic in `analyzeCall` that
211 // computes the hash.223 // computes the hash.
212 for (key.args) |arg| {224 for (key.args) |arg| {
213 arg.hash(&hasher, ctx.target);225 arg.hash(&hasher, ctx.module);
214 }226 }
215227
216 return hasher.final();228 return hasher.final();
...@@ -231,9 +243,17 @@ pub const GlobalEmitH = struct {...@@ -231,9 +243,17 @@ pub const GlobalEmitH = struct {
231 /// When emit_h is non-null, each Decl gets one more compile error slot for243 /// When emit_h is non-null, each Decl gets one more compile error slot for
232 /// emit-h failing for that Decl. This table is also how we tell if a Decl has244 /// emit-h failing for that Decl. This table is also how we tell if a Decl has
233 /// failed emit-h or succeeded.245 /// failed emit-h or succeeded.
234 failed_decls: std.AutoArrayHashMapUnmanaged(*Decl, *ErrorMsg) = .{},246 failed_decls: std.AutoArrayHashMapUnmanaged(Decl.Index, *ErrorMsg) = .{},
235 /// Tracks all decls in order to iterate over them and emit .h code for them.247 /// Tracks all decls in order to iterate over them and emit .h code for them.
236 decl_table: std.AutoArrayHashMapUnmanaged(*Decl, void) = .{},248 decl_table: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{},
249 /// Similar to the allocated_decls field of Module, this is where `EmitH` objects
250 /// are allocated. There will be exactly one EmitH object per Decl object, with
251 /// identical indexes.
252 allocated_emit_h: std.SegmentedList(EmitH, 0) = .{},
253
254 pub fn declPtr(global_emit_h: *GlobalEmitH, decl_index: Decl.Index) *EmitH {
255 return global_emit_h.allocated_emit_h.at(@enumToInt(decl_index));
256 }
237};257};
238258
239pub const ErrorInt = u32;259pub const ErrorInt = u32;
...@@ -244,12 +264,12 @@ pub const Export = struct {...@@ -244,12 +264,12 @@ pub const Export = struct {
244 /// Represents the position of the export, if any, in the output file.264 /// Represents the position of the export, if any, in the output file.
245 link: link.File.Export,265 link: link.File.Export,
246 /// The Decl that performs the export. Note that this is *not* the Decl being exported.266 /// The Decl that performs the export. Note that this is *not* the Decl being exported.
247 owner_decl: *Decl,267 owner_decl: Decl.Index,
248 /// The Decl containing the export statement. Inline function calls268 /// The Decl containing the export statement. Inline function calls
249 /// may cause this to be different from the owner_decl.269 /// may cause this to be different from the owner_decl.
250 src_decl: *Decl,270 src_decl: Decl.Index,
251 /// The Decl being exported. Note this is *not* the Decl performing the export.271 /// The Decl being exported. Note this is *not* the Decl performing the export.
252 exported_decl: *Decl,272 exported_decl: Decl.Index,
253 status: enum {273 status: enum {
254 in_progress,274 in_progress,
255 failed,275 failed,
...@@ -259,22 +279,16 @@ pub const Export = struct {...@@ -259,22 +279,16 @@ pub const Export = struct {
259 complete,279 complete,
260 },280 },
261281
262 pub fn getSrcLoc(exp: Export) SrcLoc {282 pub fn getSrcLoc(exp: Export, mod: *Module) SrcLoc {
283 const src_decl = mod.declPtr(exp.src_decl);
263 return .{284 return .{
264 .file_scope = exp.src_decl.getFileScope(),285 .file_scope = src_decl.getFileScope(),
265 .parent_decl_node = exp.src_decl.src_node,286 .parent_decl_node = src_decl.src_node,
266 .lazy = exp.src,287 .lazy = exp.src,
267 };288 };
268 }289 }
269};290};
270291
271/// When Module emit_h field is non-null, each Decl is allocated via this struct, so that
272/// there can be EmitH state attached to each Decl.
273pub const DeclPlusEmitH = struct {
274 decl: Decl,
275 emit_h: EmitH,
276};
277
278pub const CaptureScope = struct {292pub const CaptureScope = struct {
279 parent: ?*CaptureScope,293 parent: ?*CaptureScope,
280294
...@@ -458,36 +472,33 @@ pub const Decl = struct {...@@ -458,36 +472,33 @@ pub const Decl = struct {
458 /// typed_value may need to be regenerated.472 /// typed_value may need to be regenerated.
459 dependencies: DepsTable = .{},473 dependencies: DepsTable = .{},
460474
461 pub const DepsTable = std.AutoArrayHashMapUnmanaged(*Decl, void);475 pub const Index = enum(u32) {
462476 _,
463 pub fn clearName(decl: *Decl, gpa: Allocator) void {
464 gpa.free(mem.sliceTo(decl.name, 0));
465 decl.name = undefined;
466 }
467477
468 pub fn destroy(decl: *Decl, module: *Module) void {478 pub fn toOptional(i: Index) OptionalIndex {
469 const gpa = module.gpa;479 return @intToEnum(OptionalIndex, @enumToInt(i));
470 log.debug("destroy {*} ({s})", .{ decl, decl.name });
471 _ = module.test_functions.swapRemove(decl);
472 if (decl.deletion_flag) {
473 assert(module.deletion_set.swapRemove(decl));
474 }480 }
475 if (decl.has_tv) {481 };
476 if (decl.getInnerNamespace()) |namespace| {482
477 namespace.destroyDecls(module);483 pub const OptionalIndex = enum(u32) {
478 }484 none = std.math.maxInt(u32),
479 decl.clearValues(gpa);485 _,
486
487 pub fn init(oi: ?Index) OptionalIndex {
488 return oi orelse .none;
480 }489 }
481 decl.dependants.deinit(gpa);490
482 decl.dependencies.deinit(gpa);491 pub fn unwrap(oi: OptionalIndex) ?Index {
483 decl.clearName(gpa);492 if (oi == .none) return null;
484 if (module.emit_h != null) {493 return @intToEnum(Index, @enumToInt(oi));
485 const decl_plus_emit_h = @fieldParentPtr(DeclPlusEmitH, "decl", decl);
486 decl_plus_emit_h.emit_h.fwd_decl.deinit(gpa);
487 gpa.destroy(decl_plus_emit_h);
488 } else {
489 gpa.destroy(decl);
490 }494 }
495 };
496
497 pub const DepsTable = std.AutoArrayHashMapUnmanaged(Decl.Index, void);
498
499 pub fn clearName(decl: *Decl, gpa: Allocator) void {
500 gpa.free(mem.sliceTo(decl.name, 0));
501 decl.name = undefined;
491 }502 }
492503
493 pub fn clearValues(decl: *Decl, gpa: Allocator) void {504 pub fn clearValues(decl: *Decl, gpa: Allocator) void {
...@@ -573,13 +584,6 @@ pub const Decl = struct {...@@ -573,13 +584,6 @@ pub const Decl = struct {
573 return @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);584 return @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);
574 }585 }
575586
576 /// Returns true if and only if the Decl is the top level struct associated with a File.
577 pub fn isRoot(decl: *const Decl) bool {
578 if (decl.src_namespace.parent != null)
579 return false;
580 return decl == decl.src_namespace.getDecl();
581 }
582
583 pub fn relativeToLine(decl: Decl, offset: u32) u32 {587 pub fn relativeToLine(decl: Decl, offset: u32) u32 {
584 return decl.src_line + offset;588 return decl.src_line + offset;
585 }589 }
...@@ -622,20 +626,20 @@ pub const Decl = struct {...@@ -622,20 +626,20 @@ pub const Decl = struct {
622 return tree.tokens.items(.start)[decl.srcToken()];626 return tree.tokens.items(.start)[decl.srcToken()];
623 }627 }
624628
625 pub fn renderFullyQualifiedName(decl: Decl, writer: anytype) !void {629 pub fn renderFullyQualifiedName(decl: Decl, mod: *Module, writer: anytype) !void {
626 const unqualified_name = mem.sliceTo(decl.name, 0);630 const unqualified_name = mem.sliceTo(decl.name, 0);
627 return decl.src_namespace.renderFullyQualifiedName(unqualified_name, writer);631 return decl.src_namespace.renderFullyQualifiedName(mod, unqualified_name, writer);
628 }632 }
629633
630 pub fn renderFullyQualifiedDebugName(decl: Decl, writer: anytype) !void {634 pub fn renderFullyQualifiedDebugName(decl: Decl, mod: *Module, writer: anytype) !void {
631 const unqualified_name = mem.sliceTo(decl.name, 0);635 const unqualified_name = mem.sliceTo(decl.name, 0);
632 return decl.src_namespace.renderFullyQualifiedDebugName(unqualified_name, writer);636 return decl.src_namespace.renderFullyQualifiedDebugName(mod, unqualified_name, writer);
633 }637 }
634638
635 pub fn getFullyQualifiedName(decl: Decl, gpa: Allocator) ![:0]u8 {639 pub fn getFullyQualifiedName(decl: Decl, mod: *Module) ![:0]u8 {
636 var buffer = std.ArrayList(u8).init(gpa);640 var buffer = std.ArrayList(u8).init(mod.gpa);
637 defer buffer.deinit();641 defer buffer.deinit();
638 try decl.renderFullyQualifiedName(buffer.writer());642 try decl.renderFullyQualifiedName(mod, buffer.writer());
639 return buffer.toOwnedSliceSentinel(0);643 return buffer.toOwnedSliceSentinel(0);
640 }644 }
641645
...@@ -662,7 +666,6 @@ pub const Decl = struct {...@@ -662,7 +666,6 @@ pub const Decl = struct {
662 if (!decl.owns_tv) return null;666 if (!decl.owns_tv) return null;
663 const ty = (decl.val.castTag(.ty) orelse return null).data;667 const ty = (decl.val.castTag(.ty) orelse return null).data;
664 const struct_obj = (ty.castTag(.@"struct") orelse return null).data;668 const struct_obj = (ty.castTag(.@"struct") orelse return null).data;
665 assert(struct_obj.owner_decl == decl);
666 return struct_obj;669 return struct_obj;
667 }670 }
668671
...@@ -672,7 +675,6 @@ pub const Decl = struct {...@@ -672,7 +675,6 @@ pub const Decl = struct {
672 if (!decl.owns_tv) return null;675 if (!decl.owns_tv) return null;
673 const ty = (decl.val.castTag(.ty) orelse return null).data;676 const ty = (decl.val.castTag(.ty) orelse return null).data;
674 const union_obj = (ty.cast(Type.Payload.Union) orelse return null).data;677 const union_obj = (ty.cast(Type.Payload.Union) orelse return null).data;
675 assert(union_obj.owner_decl == decl);
676 return union_obj;678 return union_obj;
677 }679 }
678680
...@@ -681,7 +683,6 @@ pub const Decl = struct {...@@ -681,7 +683,6 @@ pub const Decl = struct {
681 pub fn getFunction(decl: *const Decl) ?*Fn {683 pub fn getFunction(decl: *const Decl) ?*Fn {
682 if (!decl.owns_tv) return null;684 if (!decl.owns_tv) return null;
683 const func = (decl.val.castTag(.function) orelse return null).data;685 const func = (decl.val.castTag(.function) orelse return null).data;
684 assert(func.owner_decl == decl);
685 return func;686 return func;
686 }687 }
687688
...@@ -690,16 +691,14 @@ pub const Decl = struct {...@@ -690,16 +691,14 @@ pub const Decl = struct {
690 pub fn getExternFn(decl: *const Decl) ?*ExternFn {691 pub fn getExternFn(decl: *const Decl) ?*ExternFn {
691 if (!decl.owns_tv) return null;692 if (!decl.owns_tv) return null;
692 const extern_fn = (decl.val.castTag(.extern_fn) orelse return null).data;693 const extern_fn = (decl.val.castTag(.extern_fn) orelse return null).data;
693 assert(extern_fn.owner_decl == decl);
694 return extern_fn;694 return extern_fn;
695 }695 }
696696
697 /// If the Decl has a value and it is a variable, returns it,697 /// If the Decl has a value and it is a variable, returns it,
698 /// otherwise null.698 /// otherwise null.
699 pub fn getVariable(decl: *Decl) ?*Var {699 pub fn getVariable(decl: *const Decl) ?*Var {
700 if (!decl.owns_tv) return null;700 if (!decl.owns_tv) return null;
701 const variable = (decl.val.castTag(.variable) orelse return null).data;701 const variable = (decl.val.castTag(.variable) orelse return null).data;
702 assert(variable.owner_decl == decl);
703 return variable;702 return variable;
704 }703 }
705704
...@@ -712,12 +711,10 @@ pub const Decl = struct {...@@ -712,12 +711,10 @@ pub const Decl = struct {
712 switch (ty.tag()) {711 switch (ty.tag()) {
713 .@"struct" => {712 .@"struct" => {
714 const struct_obj = ty.castTag(.@"struct").?.data;713 const struct_obj = ty.castTag(.@"struct").?.data;
715 assert(struct_obj.owner_decl == decl);
716 return &struct_obj.namespace;714 return &struct_obj.namespace;
717 },715 },
718 .enum_full, .enum_nonexhaustive => {716 .enum_full, .enum_nonexhaustive => {
719 const enum_obj = ty.cast(Type.Payload.EnumFull).?.data;717 const enum_obj = ty.cast(Type.Payload.EnumFull).?.data;
720 assert(enum_obj.owner_decl == decl);
721 return &enum_obj.namespace;718 return &enum_obj.namespace;
722 },719 },
723 .empty_struct => {720 .empty_struct => {
...@@ -725,12 +722,10 @@ pub const Decl = struct {...@@ -725,12 +722,10 @@ pub const Decl = struct {
725 },722 },
726 .@"opaque" => {723 .@"opaque" => {
727 const opaque_obj = ty.cast(Type.Payload.Opaque).?.data;724 const opaque_obj = ty.cast(Type.Payload.Opaque).?.data;
728 assert(opaque_obj.owner_decl == decl);
729 return &opaque_obj.namespace;725 return &opaque_obj.namespace;
730 },726 },
731 .@"union", .union_tagged => {727 .@"union", .union_tagged => {
732 const union_obj = ty.cast(Type.Payload.Union).?.data;728 const union_obj = ty.cast(Type.Payload.Union).?.data;
733 assert(union_obj.owner_decl == decl);
734 return &union_obj.namespace;729 return &union_obj.namespace;
735 },730 },
736731
...@@ -757,17 +752,11 @@ pub const Decl = struct {...@@ -757,17 +752,11 @@ pub const Decl = struct {
757 return decl.src_namespace.file_scope;752 return decl.src_namespace.file_scope;
758 }753 }
759754
760 pub fn getEmitH(decl: *Decl, module: *Module) *EmitH {755 pub fn removeDependant(decl: *Decl, other: Decl.Index) void {
761 assert(module.emit_h != null);
762 const decl_plus_emit_h = @fieldParentPtr(DeclPlusEmitH, "decl", decl);
763 return &decl_plus_emit_h.emit_h;
764 }
765
766 pub fn removeDependant(decl: *Decl, other: *Decl) void {
767 assert(decl.dependants.swapRemove(other));756 assert(decl.dependants.swapRemove(other));
768 }757 }
769758
770 pub fn removeDependency(decl: *Decl, other: *Decl) void {759 pub fn removeDependency(decl: *Decl, other: Decl.Index) void {
771 assert(decl.dependencies.swapRemove(other));760 assert(decl.dependencies.swapRemove(other));
772 }761 }
773762
...@@ -790,16 +779,6 @@ pub const Decl = struct {...@@ -790,16 +779,6 @@ pub const Decl = struct {
790 return decl.ty.abiAlignment(target);779 return decl.ty.abiAlignment(target);
791 }780 }
792 }781 }
793
794 pub fn markAlive(decl: *Decl) void {
795 if (decl.alive) return;
796 decl.alive = true;
797
798 // This is the first time we are marking this Decl alive. We must
799 // therefore recurse into its value and mark any Decl it references
800 // as also alive, so that any Decl referenced does not get garbage collected.
801 decl.val.markReferencedDeclsAlive();
802 }
803};782};
804783
805/// This state is attached to every Decl when Module emit_h is non-null.784/// This state is attached to every Decl when Module emit_h is non-null.
...@@ -810,7 +789,7 @@ pub const EmitH = struct {...@@ -810,7 +789,7 @@ pub const EmitH = struct {
810/// Represents the data that an explicit error set syntax provides.789/// Represents the data that an explicit error set syntax provides.
811pub const ErrorSet = struct {790pub const ErrorSet = struct {
812 /// The Decl that corresponds to the error set itself.791 /// The Decl that corresponds to the error set itself.
813 owner_decl: *Decl,792 owner_decl: Decl.Index,
814 /// Offset from Decl node index, points to the error set AST node.793 /// Offset from Decl node index, points to the error set AST node.
815 node_offset: i32,794 node_offset: i32,
816 /// The string bytes are stored in the owner Decl arena.795 /// The string bytes are stored in the owner Decl arena.
...@@ -819,10 +798,11 @@ pub const ErrorSet = struct {...@@ -819,10 +798,11 @@ pub const ErrorSet = struct {
819798
820 pub const NameMap = std.StringArrayHashMapUnmanaged(void);799 pub const NameMap = std.StringArrayHashMapUnmanaged(void);
821800
822 pub fn srcLoc(self: ErrorSet) SrcLoc {801 pub fn srcLoc(self: ErrorSet, mod: *Module) SrcLoc {
802 const owner_decl = mod.declPtr(self.owner_decl);
823 return .{803 return .{
824 .file_scope = self.owner_decl.getFileScope(),804 .file_scope = owner_decl.getFileScope(),
825 .parent_decl_node = self.owner_decl.src_node,805 .parent_decl_node = owner_decl.src_node,
826 .lazy = .{ .node_offset = self.node_offset },806 .lazy = .{ .node_offset = self.node_offset },
827 };807 };
828 }808 }
...@@ -844,12 +824,12 @@ pub const PropertyBoolean = enum { no, yes, unknown, wip };...@@ -844,12 +824,12 @@ pub const PropertyBoolean = enum { no, yes, unknown, wip };
844824
845/// Represents the data that a struct declaration provides.825/// Represents the data that a struct declaration provides.
846pub const Struct = struct {826pub const Struct = struct {
847 /// The Decl that corresponds to the struct itself.
848 owner_decl: *Decl,
849 /// Set of field names in declaration order.827 /// Set of field names in declaration order.
850 fields: Fields,828 fields: Fields,
851 /// Represents the declarations inside this struct.829 /// Represents the declarations inside this struct.
852 namespace: Namespace,830 namespace: Namespace,
831 /// The Decl that corresponds to the struct itself.
832 owner_decl: Decl.Index,
853 /// Offset from `owner_decl`, points to the struct AST node.833 /// Offset from `owner_decl`, points to the struct AST node.
854 node_offset: i32,834 node_offset: i32,
855 /// Index of the struct_decl ZIR instruction.835 /// Index of the struct_decl ZIR instruction.
...@@ -900,30 +880,32 @@ pub const Struct = struct {...@@ -900,30 +880,32 @@ pub const Struct = struct {
900 }880 }
901 };881 };
902882
903 pub fn getFullyQualifiedName(s: *Struct, gpa: Allocator) ![:0]u8 {883 pub fn getFullyQualifiedName(s: *Struct, mod: *Module) ![:0]u8 {
904 return s.owner_decl.getFullyQualifiedName(gpa);884 return mod.declPtr(s.owner_decl).getFullyQualifiedName(mod);
905 }885 }
906886
907 pub fn srcLoc(s: Struct) SrcLoc {887 pub fn srcLoc(s: Struct, mod: *Module) SrcLoc {
888 const owner_decl = mod.declPtr(s.owner_decl);
908 return .{889 return .{
909 .file_scope = s.owner_decl.getFileScope(),890 .file_scope = owner_decl.getFileScope(),
910 .parent_decl_node = s.owner_decl.src_node,891 .parent_decl_node = owner_decl.src_node,
911 .lazy = .{ .node_offset = s.node_offset },892 .lazy = .{ .node_offset = s.node_offset },
912 };893 };
913 }894 }
914895
915 pub fn fieldSrcLoc(s: Struct, gpa: Allocator, query: FieldSrcQuery) SrcLoc {896 pub fn fieldSrcLoc(s: Struct, mod: *Module, query: FieldSrcQuery) SrcLoc {
916 @setCold(true);897 @setCold(true);
917 const tree = s.owner_decl.getFileScope().getTree(gpa) catch |err| {898 const owner_decl = mod.declPtr(s.owner_decl);
899 const file = owner_decl.getFileScope();
900 const tree = file.getTree(mod.gpa) catch |err| {
918 // In this case we emit a warning + a less precise source location.901 // In this case we emit a warning + a less precise source location.
919 log.warn("unable to load {s}: {s}", .{902 log.warn("unable to load {s}: {s}", .{
920 s.owner_decl.getFileScope().sub_file_path, @errorName(err),903 file.sub_file_path, @errorName(err),
921 });904 });
922 return s.srcLoc();905 return s.srcLoc(mod);
923 };906 };
924 const node = s.owner_decl.relativeToNodeIndex(s.node_offset);907 const node = owner_decl.relativeToNodeIndex(s.node_offset);
925 const node_tags = tree.nodes.items(.tag);908 const node_tags = tree.nodes.items(.tag);
926 const file = s.owner_decl.getFileScope();
927 switch (node_tags[node]) {909 switch (node_tags[node]) {
928 .container_decl,910 .container_decl,
929 .container_decl_trailing,911 .container_decl_trailing,
...@@ -1013,18 +995,19 @@ pub const Struct = struct {...@@ -1013,18 +995,19 @@ pub const Struct = struct {
1013/// the number of fields.995/// the number of fields.
1014pub const EnumSimple = struct {996pub const EnumSimple = struct {
1015 /// The Decl that corresponds to the enum itself.997 /// The Decl that corresponds to the enum itself.
1016 owner_decl: *Decl,998 owner_decl: Decl.Index,
1017 /// Set of field names in declaration order.
1018 fields: NameMap,
1019 /// Offset from `owner_decl`, points to the enum decl AST node.999 /// Offset from `owner_decl`, points to the enum decl AST node.
1020 node_offset: i32,1000 node_offset: i32,
1001 /// Set of field names in declaration order.
1002 fields: NameMap,
10211003
1022 pub const NameMap = EnumFull.NameMap;1004 pub const NameMap = EnumFull.NameMap;
10231005
1024 pub fn srcLoc(self: EnumSimple) SrcLoc {1006 pub fn srcLoc(self: EnumSimple, mod: *Module) SrcLoc {
1007 const owner_decl = mod.declPtr(self.owner_decl);
1025 return .{1008 return .{
1026 .file_scope = self.owner_decl.getFileScope(),1009 .file_scope = owner_decl.getFileScope(),
1027 .parent_decl_node = self.owner_decl.src_node,1010 .parent_decl_node = owner_decl.src_node,
1028 .lazy = .{ .node_offset = self.node_offset },1011 .lazy = .{ .node_offset = self.node_offset },
1029 };1012 };
1030 }1013 }
...@@ -1035,7 +1018,9 @@ pub const EnumSimple = struct {...@@ -1035,7 +1018,9 @@ pub const EnumSimple = struct {
1035/// are explicitly provided.1018/// are explicitly provided.
1036pub const EnumNumbered = struct {1019pub const EnumNumbered = struct {
1037 /// The Decl that corresponds to the enum itself.1020 /// The Decl that corresponds to the enum itself.
1038 owner_decl: *Decl,1021 owner_decl: Decl.Index,
1022 /// Offset from `owner_decl`, points to the enum decl AST node.
1023 node_offset: i32,
1039 /// An integer type which is used for the numerical value of the enum.1024 /// An integer type which is used for the numerical value of the enum.
1040 /// Whether zig chooses this type or the user specifies it, it is stored here.1025 /// Whether zig chooses this type or the user specifies it, it is stored here.
1041 tag_ty: Type,1026 tag_ty: Type,
...@@ -1045,16 +1030,15 @@ pub const EnumNumbered = struct {...@@ -1045,16 +1030,15 @@ pub const EnumNumbered = struct {
1045 /// Entries are in declaration order, same as `fields`.1030 /// Entries are in declaration order, same as `fields`.
1046 /// If this hash map is empty, it means the enum tags are auto-numbered.1031 /// If this hash map is empty, it means the enum tags are auto-numbered.
1047 values: ValueMap,1032 values: ValueMap,
1048 /// Offset from `owner_decl`, points to the enum decl AST node.
1049 node_offset: i32,
10501033
1051 pub const NameMap = EnumFull.NameMap;1034 pub const NameMap = EnumFull.NameMap;
1052 pub const ValueMap = EnumFull.ValueMap;1035 pub const ValueMap = EnumFull.ValueMap;
10531036
1054 pub fn srcLoc(self: EnumNumbered) SrcLoc {1037 pub fn srcLoc(self: EnumNumbered, mod: *Module) SrcLoc {
1038 const owner_decl = mod.declPtr(self.owner_decl);
1055 return .{1039 return .{
1056 .file_scope = self.owner_decl.getFileScope(),1040 .file_scope = owner_decl.getFileScope(),
1057 .parent_decl_node = self.owner_decl.src_node,1041 .parent_decl_node = owner_decl.src_node,
1058 .lazy = .{ .node_offset = self.node_offset },1042 .lazy = .{ .node_offset = self.node_offset },
1059 };1043 };
1060 }1044 }
...@@ -1064,7 +1048,9 @@ pub const EnumNumbered = struct {...@@ -1064,7 +1048,9 @@ pub const EnumNumbered = struct {
1064/// at least one tag value explicitly specified, or at least one declaration.1048/// at least one tag value explicitly specified, or at least one declaration.
1065pub const EnumFull = struct {1049pub const EnumFull = struct {
1066 /// The Decl that corresponds to the enum itself.1050 /// The Decl that corresponds to the enum itself.
1067 owner_decl: *Decl,1051 owner_decl: Decl.Index,
1052 /// Offset from `owner_decl`, points to the enum decl AST node.
1053 node_offset: i32,
1068 /// An integer type which is used for the numerical value of the enum.1054 /// An integer type which is used for the numerical value of the enum.
1069 /// Whether zig chooses this type or the user specifies it, it is stored here.1055 /// Whether zig chooses this type or the user specifies it, it is stored here.
1070 tag_ty: Type,1056 tag_ty: Type,
...@@ -1076,26 +1062,23 @@ pub const EnumFull = struct {...@@ -1076,26 +1062,23 @@ pub const EnumFull = struct {
1076 values: ValueMap,1062 values: ValueMap,
1077 /// Represents the declarations inside this enum.1063 /// Represents the declarations inside this enum.
1078 namespace: Namespace,1064 namespace: Namespace,
1079 /// Offset from `owner_decl`, points to the enum decl AST node.
1080 node_offset: i32,
1081 /// true if zig inferred this tag type, false if user specified it1065 /// true if zig inferred this tag type, false if user specified it
1082 tag_ty_inferred: bool,1066 tag_ty_inferred: bool,
10831067
1084 pub const NameMap = std.StringArrayHashMapUnmanaged(void);1068 pub const NameMap = std.StringArrayHashMapUnmanaged(void);
1085 pub const ValueMap = std.ArrayHashMapUnmanaged(Value, void, Value.ArrayHashContext, false);1069 pub const ValueMap = std.ArrayHashMapUnmanaged(Value, void, Value.ArrayHashContext, false);
10861070
1087 pub fn srcLoc(self: EnumFull) SrcLoc {1071 pub fn srcLoc(self: EnumFull, mod: *Module) SrcLoc {
1072 const owner_decl = mod.declPtr(self.owner_decl);
1088 return .{1073 return .{
1089 .file_scope = self.owner_decl.getFileScope(),1074 .file_scope = owner_decl.getFileScope(),
1090 .parent_decl_node = self.owner_decl.src_node,1075 .parent_decl_node = owner_decl.src_node,
1091 .lazy = .{ .node_offset = self.node_offset },1076 .lazy = .{ .node_offset = self.node_offset },
1092 };1077 };
1093 }1078 }
1094};1079};
10951080
1096pub const Union = struct {1081pub const Union = struct {
1097 /// The Decl that corresponds to the union itself.
1098 owner_decl: *Decl,
1099 /// An enum type which is used for the tag of the union.1082 /// An enum type which is used for the tag of the union.
1100 /// This type is created even for untagged unions, even when the memory1083 /// This type is created even for untagged unions, even when the memory
1101 /// layout does not store the tag.1084 /// layout does not store the tag.
...@@ -1106,6 +1089,8 @@ pub const Union = struct {...@@ -1106,6 +1089,8 @@ pub const Union = struct {
1106 fields: Fields,1089 fields: Fields,
1107 /// Represents the declarations inside this union.1090 /// Represents the declarations inside this union.
1108 namespace: Namespace,1091 namespace: Namespace,
1092 /// The Decl that corresponds to the union itself.
1093 owner_decl: Decl.Index,
1109 /// Offset from `owner_decl`, points to the union decl AST node.1094 /// Offset from `owner_decl`, points to the union decl AST node.
1110 node_offset: i32,1095 node_offset: i32,
1111 /// Index of the union_decl ZIR instruction.1096 /// Index of the union_decl ZIR instruction.
...@@ -1145,30 +1130,32 @@ pub const Union = struct {...@@ -1145,30 +1130,32 @@ pub const Union = struct {
11451130
1146 pub const Fields = std.StringArrayHashMapUnmanaged(Field);1131 pub const Fields = std.StringArrayHashMapUnmanaged(Field);
11471132
1148 pub fn getFullyQualifiedName(s: *Union, gpa: Allocator) ![:0]u8 {1133 pub fn getFullyQualifiedName(s: *Union, mod: *Module) ![:0]u8 {
1149 return s.owner_decl.getFullyQualifiedName(gpa);1134 return mod.declPtr(s.owner_decl).getFullyQualifiedName(mod);
1150 }1135 }
11511136
1152 pub fn srcLoc(self: Union) SrcLoc {1137 pub fn srcLoc(self: Union, mod: *Module) SrcLoc {
1138 const owner_decl = mod.declPtr(self.owner_decl);
1153 return .{1139 return .{
1154 .file_scope = self.owner_decl.getFileScope(),1140 .file_scope = owner_decl.getFileScope(),
1155 .parent_decl_node = self.owner_decl.src_node,1141 .parent_decl_node = owner_decl.src_node,
1156 .lazy = .{ .node_offset = self.node_offset },1142 .lazy = .{ .node_offset = self.node_offset },
1157 };1143 };
1158 }1144 }
11591145
1160 pub fn fieldSrcLoc(u: Union, gpa: Allocator, query: FieldSrcQuery) SrcLoc {1146 pub fn fieldSrcLoc(u: Union, mod: *Module, query: FieldSrcQuery) SrcLoc {
1161 @setCold(true);1147 @setCold(true);
1162 const tree = u.owner_decl.getFileScope().getTree(gpa) catch |err| {1148 const owner_decl = mod.declPtr(u.owner_decl);
1149 const file = owner_decl.getFileScope();
1150 const tree = file.getTree(mod.gpa) catch |err| {
1163 // In this case we emit a warning + a less precise source location.1151 // In this case we emit a warning + a less precise source location.
1164 log.warn("unable to load {s}: {s}", .{1152 log.warn("unable to load {s}: {s}", .{
1165 u.owner_decl.getFileScope().sub_file_path, @errorName(err),1153 file.sub_file_path, @errorName(err),
1166 });1154 });
1167 return u.srcLoc();1155 return u.srcLoc(mod);
1168 };1156 };
1169 const node = u.owner_decl.relativeToNodeIndex(u.node_offset);1157 const node = owner_decl.relativeToNodeIndex(u.node_offset);
1170 const node_tags = tree.nodes.items(.tag);1158 const node_tags = tree.nodes.items(.tag);
1171 const file = u.owner_decl.getFileScope();
1172 switch (node_tags[node]) {1159 switch (node_tags[node]) {
1173 .container_decl,1160 .container_decl,
1174 .container_decl_trailing,1161 .container_decl_trailing,
...@@ -1348,22 +1335,23 @@ pub const Union = struct {...@@ -1348,22 +1335,23 @@ pub const Union = struct {
13481335
1349pub const Opaque = struct {1336pub const Opaque = struct {
1350 /// The Decl that corresponds to the opaque itself.1337 /// The Decl that corresponds to the opaque itself.
1351 owner_decl: *Decl,1338 owner_decl: Decl.Index,
1352 /// Represents the declarations inside this opaque.
1353 namespace: Namespace,
1354 /// Offset from `owner_decl`, points to the opaque decl AST node.1339 /// Offset from `owner_decl`, points to the opaque decl AST node.
1355 node_offset: i32,1340 node_offset: i32,
1341 /// Represents the declarations inside this opaque.
1342 namespace: Namespace,
13561343
1357 pub fn srcLoc(self: Opaque) SrcLoc {1344 pub fn srcLoc(self: Opaque, mod: *Module) SrcLoc {
1345 const owner_decl = mod.declPtr(self.owner_decl);
1358 return .{1346 return .{
1359 .file_scope = self.owner_decl.getFileScope(),1347 .file_scope = owner_decl.getFileScope(),
1360 .parent_decl_node = self.owner_decl.src_node,1348 .parent_decl_node = owner_decl.src_node,
1361 .lazy = .{ .node_offset = self.node_offset },1349 .lazy = .{ .node_offset = self.node_offset },
1362 };1350 };
1363 }1351 }
13641352
1365 pub fn getFullyQualifiedName(s: *Opaque, gpa: Allocator) ![:0]u8 {1353 pub fn getFullyQualifiedName(s: *Opaque, mod: *Module) ![:0]u8 {
1366 return s.owner_decl.getFullyQualifiedName(gpa);1354 return mod.declPtr(s.owner_decl).getFullyQualifiedName(mod);
1367 }1355 }
1368};1356};
13691357
...@@ -1371,7 +1359,7 @@ pub const Opaque = struct {...@@ -1371,7 +1359,7 @@ pub const Opaque = struct {
1371/// arena allocator.1359/// arena allocator.
1372pub const ExternFn = struct {1360pub const ExternFn = struct {
1373 /// The Decl that corresponds to the function itself.1361 /// The Decl that corresponds to the function itself.
1374 owner_decl: *Decl,1362 owner_decl: Decl.Index,
1375 /// Library name if specified.1363 /// Library name if specified.
1376 /// For example `extern "c" fn write(...) usize` would have 'c' as library name.1364 /// For example `extern "c" fn write(...) usize` would have 'c' as library name.
1377 /// Allocated with Module's allocator; outlives the ZIR code.1365 /// Allocated with Module's allocator; outlives the ZIR code.
...@@ -1389,7 +1377,12 @@ pub const ExternFn = struct {...@@ -1389,7 +1377,12 @@ pub const ExternFn = struct {
1389/// instead.1377/// instead.
1390pub const Fn = struct {1378pub const Fn = struct {
1391 /// The Decl that corresponds to the function itself.1379 /// The Decl that corresponds to the function itself.
1392 owner_decl: *Decl,1380 owner_decl: Decl.Index,
1381 /// The ZIR instruction that is a function instruction. Use this to find
1382 /// the body. We store this rather than the body directly so that when ZIR
1383 /// is regenerated on update(), we can map this to the new corresponding
1384 /// ZIR instruction.
1385 zir_body_inst: Zir.Inst.Index,
1393 /// If this is not null, this function is a generic function instantiation, and1386 /// If this is not null, this function is a generic function instantiation, and
1394 /// there is a `TypedValue` here for each parameter of the function.1387 /// there is a `TypedValue` here for each parameter of the function.
1395 /// Non-comptime parameters are marked with a `generic_poison` for the value.1388 /// Non-comptime parameters are marked with a `generic_poison` for the value.
...@@ -1403,11 +1396,6 @@ pub const Fn = struct {...@@ -1403,11 +1396,6 @@ pub const Fn = struct {
1403 /// parameter and tells whether it is anytype.1396 /// parameter and tells whether it is anytype.
1404 /// TODO apply the same enhancement for param_names below to this field.1397 /// TODO apply the same enhancement for param_names below to this field.
1405 anytype_args: [*]bool,1398 anytype_args: [*]bool,
1406 /// The ZIR instruction that is a function instruction. Use this to find
1407 /// the body. We store this rather than the body directly so that when ZIR
1408 /// is regenerated on update(), we can map this to the new corresponding
1409 /// ZIR instruction.
1410 zir_body_inst: Zir.Inst.Index,
14111399
1412 /// Prefer to use `getParamName` to access this because of the future improvement1400 /// Prefer to use `getParamName` to access this because of the future improvement
1413 /// we want to do mentioned in the TODO below.1401 /// we want to do mentioned in the TODO below.
...@@ -1537,8 +1525,9 @@ pub const Fn = struct {...@@ -1537,8 +1525,9 @@ pub const Fn = struct {
1537 return func.param_names[index];1525 return func.param_names[index];
1538 }1526 }
15391527
1540 pub fn hasInferredErrorSet(func: Fn) bool {1528 pub fn hasInferredErrorSet(func: Fn, mod: *Module) bool {
1541 const zir = func.owner_decl.getFileScope().zir;1529 const owner_decl = mod.declPtr(func.owner_decl);
1530 const zir = owner_decl.getFileScope().zir;
1542 const zir_tags = zir.instructions.items(.tag);1531 const zir_tags = zir.instructions.items(.tag);
1543 switch (zir_tags[func.zir_body_inst]) {1532 switch (zir_tags[func.zir_body_inst]) {
1544 .func => return false,1533 .func => return false,
...@@ -1556,7 +1545,7 @@ pub const Fn = struct {...@@ -1556,7 +1545,7 @@ pub const Fn = struct {
1556pub const Var = struct {1545pub const Var = struct {
1557 /// if is_extern == true this is undefined1546 /// if is_extern == true this is undefined
1558 init: Value,1547 init: Value,
1559 owner_decl: *Decl,1548 owner_decl: Decl.Index,
15601549
1561 /// Library name if specified.1550 /// Library name if specified.
1562 /// For example `extern "c" var stderrp = ...` would have 'c' as library name.1551 /// For example `extern "c" var stderrp = ...` would have 'c' as library name.
...@@ -1576,14 +1565,16 @@ pub const Var = struct {...@@ -1576,14 +1565,16 @@ pub const Var = struct {
1576};1565};
15771566
1578pub const DeclAdapter = struct {1567pub const DeclAdapter = struct {
1568 mod: *Module,
1569
1579 pub fn hash(self: @This(), s: []const u8) u32 {1570 pub fn hash(self: @This(), s: []const u8) u32 {
1580 _ = self;1571 _ = self;
1581 return @truncate(u32, std.hash.Wyhash.hash(0, s));1572 return @truncate(u32, std.hash.Wyhash.hash(0, s));
1582 }1573 }
15831574
1584 pub fn eql(self: @This(), a: []const u8, b_decl: *Decl, b_index: usize) bool {1575 pub fn eql(self: @This(), a: []const u8, b_decl_index: Decl.Index, b_index: usize) bool {
1585 _ = self;
1586 _ = b_index;1576 _ = b_index;
1577 const b_decl = self.mod.declPtr(b_decl_index);
1587 return mem.eql(u8, a, mem.sliceTo(b_decl.name, 0));1578 return mem.eql(u8, a, mem.sliceTo(b_decl.name, 0));
1588 }1579 }
1589};1580};
...@@ -1599,25 +1590,30 @@ pub const Namespace = struct {...@@ -1599,25 +1590,30 @@ pub const Namespace = struct {
1599 /// Declaration order is preserved via entry order.1590 /// Declaration order is preserved via entry order.
1600 /// Key memory is owned by `decl.name`.1591 /// Key memory is owned by `decl.name`.
1601 /// Anonymous decls are not stored here; they are kept in `anon_decls` instead.1592 /// Anonymous decls are not stored here; they are kept in `anon_decls` instead.
1602 decls: std.ArrayHashMapUnmanaged(*Decl, void, DeclContext, true) = .{},1593 decls: std.ArrayHashMapUnmanaged(Decl.Index, void, DeclContext, true) = .{},
16031594
1604 anon_decls: std.AutoArrayHashMapUnmanaged(*Decl, void) = .{},1595 anon_decls: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{},
16051596
1606 /// Key is usingnamespace Decl itself. To find the namespace being included,1597 /// Key is usingnamespace Decl itself. To find the namespace being included,
1607 /// the Decl Value has to be resolved as a Type which has a Namespace.1598 /// the Decl Value has to be resolved as a Type which has a Namespace.
1608 /// Value is whether the usingnamespace decl is marked `pub`.1599 /// Value is whether the usingnamespace decl is marked `pub`.
1609 usingnamespace_set: std.AutoHashMapUnmanaged(*Decl, bool) = .{},1600 usingnamespace_set: std.AutoHashMapUnmanaged(Decl.Index, bool) = .{},
16101601
1611 const DeclContext = struct {1602 const DeclContext = struct {
1612 pub fn hash(self: @This(), decl: *Decl) u32 {1603 module: *Module,
1613 _ = self;1604
1605 pub fn hash(ctx: @This(), decl_index: Decl.Index) u32 {
1606 const decl = ctx.module.declPtr(decl_index);
1614 return @truncate(u32, std.hash.Wyhash.hash(0, mem.sliceTo(decl.name, 0)));1607 return @truncate(u32, std.hash.Wyhash.hash(0, mem.sliceTo(decl.name, 0)));
1615 }1608 }
16161609
1617 pub fn eql(self: @This(), a: *Decl, b: *Decl, b_index: usize) bool {1610 pub fn eql(ctx: @This(), a_decl_index: Decl.Index, b_decl_index: Decl.Index, b_index: usize) bool {
1618 _ = self;
1619 _ = b_index;1611 _ = b_index;
1620 return mem.eql(u8, mem.sliceTo(a.name, 0), mem.sliceTo(b.name, 0));1612 const a_decl = ctx.module.declPtr(a_decl_index);
1613 const b_decl = ctx.module.declPtr(b_decl_index);
1614 const a_name = mem.sliceTo(a_decl.name, 0);
1615 const b_name = mem.sliceTo(b_decl.name, 0);
1616 return mem.eql(u8, a_name, b_name);
1621 }1617 }
1622 };1618 };
16231619
...@@ -1637,13 +1633,13 @@ pub const Namespace = struct {...@@ -1637,13 +1633,13 @@ pub const Namespace = struct {
1637 var anon_decls = ns.anon_decls;1633 var anon_decls = ns.anon_decls;
1638 ns.anon_decls = .{};1634 ns.anon_decls = .{};
16391635
1640 for (decls.keys()) |decl| {1636 for (decls.keys()) |decl_index| {
1641 decl.destroy(mod);1637 mod.destroyDecl(decl_index);
1642 }1638 }
1643 decls.deinit(gpa);1639 decls.deinit(gpa);
16441640
1645 for (anon_decls.keys()) |key| {1641 for (anon_decls.keys()) |key| {
1646 key.destroy(mod);1642 mod.destroyDecl(key);
1647 }1643 }
1648 anon_decls.deinit(gpa);1644 anon_decls.deinit(gpa);
1649 ns.usingnamespace_set.deinit(gpa);1645 ns.usingnamespace_set.deinit(gpa);
...@@ -1652,7 +1648,7 @@ pub const Namespace = struct {...@@ -1652,7 +1648,7 @@ pub const Namespace = struct {
1652 pub fn deleteAllDecls(1648 pub fn deleteAllDecls(
1653 ns: *Namespace,1649 ns: *Namespace,
1654 mod: *Module,1650 mod: *Module,
1655 outdated_decls: ?*std.AutoArrayHashMap(*Decl, void),1651 outdated_decls: ?*std.AutoArrayHashMap(Decl.Index, void),
1656 ) !void {1652 ) !void {
1657 const gpa = mod.gpa;1653 const gpa = mod.gpa;
16581654
...@@ -1669,13 +1665,13 @@ pub const Namespace = struct {...@@ -1669,13 +1665,13 @@ pub const Namespace = struct {
16691665
1670 for (decls.keys()) |child_decl| {1666 for (decls.keys()) |child_decl| {
1671 mod.clearDecl(child_decl, outdated_decls) catch @panic("out of memory");1667 mod.clearDecl(child_decl, outdated_decls) catch @panic("out of memory");
1672 child_decl.destroy(mod);1668 mod.destroyDecl(child_decl);
1673 }1669 }
1674 decls.deinit(gpa);1670 decls.deinit(gpa);
16751671
1676 for (anon_decls.keys()) |child_decl| {1672 for (anon_decls.keys()) |child_decl| {
1677 mod.clearDecl(child_decl, outdated_decls) catch @panic("out of memory");1673 mod.clearDecl(child_decl, outdated_decls) catch @panic("out of memory");
1678 child_decl.destroy(mod);1674 mod.destroyDecl(child_decl);
1679 }1675 }
1680 anon_decls.deinit(gpa);1676 anon_decls.deinit(gpa);
16811677
...@@ -1685,12 +1681,14 @@ pub const Namespace = struct {...@@ -1685,12 +1681,14 @@ pub const Namespace = struct {
1685 // This renders e.g. "std.fs.Dir.OpenOptions"1681 // This renders e.g. "std.fs.Dir.OpenOptions"
1686 pub fn renderFullyQualifiedName(1682 pub fn renderFullyQualifiedName(
1687 ns: Namespace,1683 ns: Namespace,
1684 mod: *Module,
1688 name: []const u8,1685 name: []const u8,
1689 writer: anytype,1686 writer: anytype,
1690 ) @TypeOf(writer).Error!void {1687 ) @TypeOf(writer).Error!void {
1691 if (ns.parent) |parent| {1688 if (ns.parent) |parent| {
1692 const decl = ns.getDecl();1689 const decl_index = ns.getDeclIndex();
1693 try parent.renderFullyQualifiedName(mem.sliceTo(decl.name, 0), writer);1690 const decl = mod.declPtr(decl_index);
1691 try parent.renderFullyQualifiedName(mod, mem.sliceTo(decl.name, 0), writer);
1694 } else {1692 } else {
1695 try ns.file_scope.renderFullyQualifiedName(writer);1693 try ns.file_scope.renderFullyQualifiedName(writer);
1696 }1694 }
...@@ -1703,13 +1701,15 @@ pub const Namespace = struct {...@@ -1703,13 +1701,15 @@ pub const Namespace = struct {
1703 /// This renders e.g. "std/fs.zig:Dir.OpenOptions"1701 /// This renders e.g. "std/fs.zig:Dir.OpenOptions"
1704 pub fn renderFullyQualifiedDebugName(1702 pub fn renderFullyQualifiedDebugName(
1705 ns: Namespace,1703 ns: Namespace,
1704 mod: *Module,
1706 name: []const u8,1705 name: []const u8,
1707 writer: anytype,1706 writer: anytype,
1708 ) @TypeOf(writer).Error!void {1707 ) @TypeOf(writer).Error!void {
1709 var separator_char: u8 = '.';1708 var separator_char: u8 = '.';
1710 if (ns.parent) |parent| {1709 if (ns.parent) |parent| {
1711 const decl = ns.getDecl();1710 const decl_index = ns.getDeclIndex();
1712 try parent.renderFullyQualifiedDebugName(mem.sliceTo(decl.name, 0), writer);1711 const decl = mod.declPtr(decl_index);
1712 try parent.renderFullyQualifiedDebugName(mod, mem.sliceTo(decl.name, 0), writer);
1713 } else {1713 } else {
1714 try ns.file_scope.renderFullyQualifiedDebugName(writer);1714 try ns.file_scope.renderFullyQualifiedDebugName(writer);
1715 separator_char = ':';1715 separator_char = ':';
...@@ -1720,12 +1720,14 @@ pub const Namespace = struct {...@@ -1720,12 +1720,14 @@ pub const Namespace = struct {
1720 }1720 }
1721 }1721 }
17221722
1723 pub fn getDecl(ns: Namespace) *Decl {1723 pub fn getDeclIndex(ns: Namespace) Decl.Index {
1724 return ns.ty.getOwnerDecl();1724 return ns.ty.getOwnerDecl();
1725 }1725 }
1726};1726};
17271727
1728pub const File = struct {1728pub const File = struct {
1729 /// The Decl of the struct that represents this File.
1730 root_decl: Decl.OptionalIndex,
1729 status: enum {1731 status: enum {
1730 never_loaded,1732 never_loaded,
1731 retryable_failure,1733 retryable_failure,
...@@ -1749,16 +1751,14 @@ pub const File = struct {...@@ -1749,16 +1751,14 @@ pub const File = struct {
1749 zir: Zir,1751 zir: Zir,
1750 /// Package that this file is a part of, managed externally.1752 /// Package that this file is a part of, managed externally.
1751 pkg: *Package,1753 pkg: *Package,
1752 /// The Decl of the struct that represents this File.
1753 root_decl: ?*Decl,
17541754
1755 /// Used by change detection algorithm, after astgen, contains the1755 /// Used by change detection algorithm, after astgen, contains the
1756 /// set of decls that existed in the previous ZIR but not in the new one.1756 /// set of decls that existed in the previous ZIR but not in the new one.
1757 deleted_decls: std.ArrayListUnmanaged(*Decl) = .{},1757 deleted_decls: std.ArrayListUnmanaged(Decl.Index) = .{},
1758 /// Used by change detection algorithm, after astgen, contains the1758 /// Used by change detection algorithm, after astgen, contains the
1759 /// set of decls that existed both in the previous ZIR and in the new one,1759 /// set of decls that existed both in the previous ZIR and in the new one,
1760 /// but their source code has been modified.1760 /// but their source code has been modified.
1761 outdated_decls: std.ArrayListUnmanaged(*Decl) = .{},1761 outdated_decls: std.ArrayListUnmanaged(Decl.Index) = .{},
17621762
1763 /// The most recent successful ZIR for this file, with no errors.1763 /// The most recent successful ZIR for this file, with no errors.
1764 /// This is only populated when a previously successful ZIR1764 /// This is only populated when a previously successful ZIR
...@@ -1798,8 +1798,8 @@ pub const File = struct {...@@ -1798,8 +1798,8 @@ pub const File = struct {
1798 log.debug("deinit File {s}", .{file.sub_file_path});1798 log.debug("deinit File {s}", .{file.sub_file_path});
1799 file.deleted_decls.deinit(gpa);1799 file.deleted_decls.deinit(gpa);
1800 file.outdated_decls.deinit(gpa);1800 file.outdated_decls.deinit(gpa);
1801 if (file.root_decl) |root_decl| {1801 if (file.root_decl.unwrap()) |root_decl| {
1802 root_decl.destroy(mod);1802 mod.destroyDecl(root_decl);
1803 }1803 }
1804 gpa.free(file.sub_file_path);1804 gpa.free(file.sub_file_path);
1805 file.unload(gpa);1805 file.unload(gpa);
...@@ -1932,7 +1932,7 @@ pub const EmbedFile = struct {...@@ -1932,7 +1932,7 @@ pub const EmbedFile = struct {
1932 /// The Decl that was created from the `@embedFile` to own this resource.1932 /// The Decl that was created from the `@embedFile` to own this resource.
1933 /// This is how zig knows what other Decl objects to invalidate if the file1933 /// This is how zig knows what other Decl objects to invalidate if the file
1934 /// changes on disk.1934 /// changes on disk.
1935 owner_decl: *Decl,1935 owner_decl: Decl.Index,
19361936
1937 fn destroy(embed_file: *EmbedFile, mod: *Module) void {1937 fn destroy(embed_file: *EmbedFile, mod: *Module) void {
1938 const gpa = mod.gpa;1938 const gpa = mod.gpa;
...@@ -2776,6 +2776,7 @@ pub fn deinit(mod: *Module) void {...@@ -2776,6 +2776,7 @@ pub fn deinit(mod: *Module) void {
2776 }2776 }
2777 emit_h.failed_decls.deinit(gpa);2777 emit_h.failed_decls.deinit(gpa);
2778 emit_h.decl_table.deinit(gpa);2778 emit_h.decl_table.deinit(gpa);
2779 emit_h.allocated_emit_h.deinit(gpa);
2779 gpa.destroy(emit_h);2780 gpa.destroy(emit_h);
2780 }2781 }
27812782
...@@ -2827,6 +2828,52 @@ pub fn deinit(mod: *Module) void {...@@ -2827,6 +2828,52 @@ pub fn deinit(mod: *Module) void {
2827 }2828 }
2828 mod.memoized_calls.deinit(gpa);2829 mod.memoized_calls.deinit(gpa);
2829 }2830 }
2831
2832 mod.decls_free_list.deinit(gpa);
2833 mod.allocated_decls.deinit(gpa);
2834}
2835
2836pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void {
2837 const gpa = mod.gpa;
2838 {
2839 const decl = mod.declPtr(decl_index);
2840 log.debug("destroy {*} ({s})", .{ decl, decl.name });
2841 _ = mod.test_functions.swapRemove(decl_index);
2842 if (decl.deletion_flag) {
2843 assert(mod.deletion_set.swapRemove(decl_index));
2844 }
2845 if (decl.has_tv) {
2846 if (decl.getInnerNamespace()) |namespace| {
2847 namespace.destroyDecls(mod);
2848 }
2849 decl.clearValues(gpa);
2850 }
2851 decl.dependants.deinit(gpa);
2852 decl.dependencies.deinit(gpa);
2853 decl.clearName(gpa);
2854 decl.* = undefined;
2855 }
2856 mod.decls_free_list.append(gpa, decl_index) catch {
2857 // In order to keep `destroyDecl` a non-fallible function, we ignore memory
2858 // allocation failures here, instead leaking the Decl until garbage collection.
2859 };
2860 if (mod.emit_h) |mod_emit_h| {
2861 const decl_emit_h = mod_emit_h.declPtr(decl_index);
2862 decl_emit_h.fwd_decl.deinit(gpa);
2863 decl_emit_h.* = undefined;
2864 }
2865}
2866
2867pub fn declPtr(mod: *Module, decl_index: Decl.Index) *Decl {
2868 return mod.allocated_decls.at(@enumToInt(decl_index));
2869}
2870
2871/// Returns true if and only if the Decl is the top level struct associated with a File.
2872pub fn declIsRoot(mod: *Module, decl_index: Decl.Index) bool {
2873 const decl = mod.declPtr(decl_index);
2874 if (decl.src_namespace.parent != null)
2875 return false;
2876 return decl_index == decl.src_namespace.getDeclIndex();
2830}2877}
28312878
2832fn freeExportList(gpa: Allocator, export_list: []*Export) void {2879fn freeExportList(gpa: Allocator, export_list: []*Export) void {
...@@ -3230,14 +3277,14 @@ pub fn astGenFile(mod: *Module, file: *File) !void {...@@ -3230,14 +3277,14 @@ pub fn astGenFile(mod: *Module, file: *File) !void {
3230 // We do not need to hold any locks at this time because all the Decl and Namespace3277 // We do not need to hold any locks at this time because all the Decl and Namespace
3231 // objects being touched are specific to this File, and the only other concurrent3278 // objects being touched are specific to this File, and the only other concurrent
3232 // tasks are touching other File objects.3279 // tasks are touching other File objects.
3233 try updateZirRefs(gpa, file, prev_zir.*);3280 try updateZirRefs(mod, file, prev_zir.*);
3234 // At this point, `file.outdated_decls` and `file.deleted_decls` are populated,3281 // At this point, `file.outdated_decls` and `file.deleted_decls` are populated,
3235 // and semantic analysis will deal with them properly.3282 // and semantic analysis will deal with them properly.
3236 // No need to keep previous ZIR.3283 // No need to keep previous ZIR.
3237 prev_zir.deinit(gpa);3284 prev_zir.deinit(gpa);
3238 gpa.destroy(prev_zir);3285 gpa.destroy(prev_zir);
3239 file.prev_zir = null;3286 file.prev_zir = null;
3240 } else if (file.root_decl) |root_decl| {3287 } else if (file.root_decl.unwrap()) |root_decl| {
3241 // This is an update, but it is the first time the File has succeeded3288 // This is an update, but it is the first time the File has succeeded
3242 // ZIR. We must mark it outdated since we have already tried to3289 // ZIR. We must mark it outdated since we have already tried to
3243 // semantically analyze it.3290 // semantically analyze it.
...@@ -3251,7 +3298,8 @@ pub fn astGenFile(mod: *Module, file: *File) !void {...@@ -3251,7 +3298,8 @@ pub fn astGenFile(mod: *Module, file: *File) !void {
3251/// * Decl.zir_index3298/// * Decl.zir_index
3252/// * Fn.zir_body_inst3299/// * Fn.zir_body_inst
3253/// * Decl.zir_decl_index3300/// * Decl.zir_decl_index
3254fn updateZirRefs(gpa: Allocator, file: *File, old_zir: Zir) !void {3301fn updateZirRefs(mod: *Module, file: *File, old_zir: Zir) !void {
3302 const gpa = mod.gpa;
3255 const new_zir = file.zir;3303 const new_zir = file.zir;
32563304
3257 // Maps from old ZIR to new ZIR, struct_decl, enum_decl, etc. Any instruction which3305 // Maps from old ZIR to new ZIR, struct_decl, enum_decl, etc. Any instruction which
...@@ -3268,10 +3316,10 @@ fn updateZirRefs(gpa: Allocator, file: *File, old_zir: Zir) !void {...@@ -3268,10 +3316,10 @@ fn updateZirRefs(gpa: Allocator, file: *File, old_zir: Zir) !void {
3268 // Walk the Decl graph, updating ZIR indexes, strings, and populating3316 // Walk the Decl graph, updating ZIR indexes, strings, and populating
3269 // the deleted and outdated lists.3317 // the deleted and outdated lists.
32703318
3271 var decl_stack: std.ArrayListUnmanaged(*Decl) = .{};3319 var decl_stack: std.ArrayListUnmanaged(Decl.Index) = .{};
3272 defer decl_stack.deinit(gpa);3320 defer decl_stack.deinit(gpa);
32733321
3274 const root_decl = file.root_decl.?;3322 const root_decl = file.root_decl.unwrap().?;
3275 try decl_stack.append(gpa, root_decl);3323 try decl_stack.append(gpa, root_decl);
32763324
3277 file.deleted_decls.clearRetainingCapacity();3325 file.deleted_decls.clearRetainingCapacity();
...@@ -3281,7 +3329,8 @@ fn updateZirRefs(gpa: Allocator, file: *File, old_zir: Zir) !void {...@@ -3281,7 +3329,8 @@ fn updateZirRefs(gpa: Allocator, file: *File, old_zir: Zir) !void {
3281 // to re-generate ZIR for the File.3329 // to re-generate ZIR for the File.
3282 try file.outdated_decls.append(gpa, root_decl);3330 try file.outdated_decls.append(gpa, root_decl);
32833331
3284 while (decl_stack.popOrNull()) |decl| {3332 while (decl_stack.popOrNull()) |decl_index| {
3333 const decl = mod.declPtr(decl_index);
3285 // Anonymous decls and the root decl have this set to 0. We still need3334 // Anonymous decls and the root decl have this set to 0. We still need
3286 // to walk them but we do not need to modify this value.3335 // to walk them but we do not need to modify this value.
3287 // Anonymous decls should not be marked outdated. They will be re-generated3336 // Anonymous decls should not be marked outdated. They will be re-generated
...@@ -3292,7 +3341,7 @@ fn updateZirRefs(gpa: Allocator, file: *File, old_zir: Zir) !void {...@@ -3292,7 +3341,7 @@ fn updateZirRefs(gpa: Allocator, file: *File, old_zir: Zir) !void {
3292 log.debug("updateZirRefs {s}: delete {*} ({s})", .{3341 log.debug("updateZirRefs {s}: delete {*} ({s})", .{
3293 file.sub_file_path, decl, decl.name,3342 file.sub_file_path, decl, decl.name,
3294 });3343 });
3295 try file.deleted_decls.append(gpa, decl);3344 try file.deleted_decls.append(gpa, decl_index);
3296 continue;3345 continue;
3297 };3346 };
3298 const old_hash = decl.contentsHashZir(old_zir);3347 const old_hash = decl.contentsHashZir(old_zir);
...@@ -3302,7 +3351,7 @@ fn updateZirRefs(gpa: Allocator, file: *File, old_zir: Zir) !void {...@@ -3302,7 +3351,7 @@ fn updateZirRefs(gpa: Allocator, file: *File, old_zir: Zir) !void {
3302 log.debug("updateZirRefs {s}: outdated {*} ({s}) {d} => {d}", .{3351 log.debug("updateZirRefs {s}: outdated {*} ({s}) {d} => {d}", .{
3303 file.sub_file_path, decl, decl.name, old_zir_decl_index, new_zir_decl_index,3352 file.sub_file_path, decl, decl.name, old_zir_decl_index, new_zir_decl_index,
3304 });3353 });
3305 try file.outdated_decls.append(gpa, decl);3354 try file.outdated_decls.append(gpa, decl_index);
3306 } else {3355 } else {
3307 log.debug("updateZirRefs {s}: unchanged {*} ({s}) {d} => {d}", .{3356 log.debug("updateZirRefs {s}: unchanged {*} ({s}) {d} => {d}", .{
3308 file.sub_file_path, decl, decl.name, old_zir_decl_index, new_zir_decl_index,3357 file.sub_file_path, decl, decl.name, old_zir_decl_index, new_zir_decl_index,
...@@ -3314,21 +3363,21 @@ fn updateZirRefs(gpa: Allocator, file: *File, old_zir: Zir) !void {...@@ -3314,21 +3363,21 @@ fn updateZirRefs(gpa: Allocator, file: *File, old_zir: Zir) !void {
33143363
3315 if (decl.getStruct()) |struct_obj| {3364 if (decl.getStruct()) |struct_obj| {
3316 struct_obj.zir_index = inst_map.get(struct_obj.zir_index) orelse {3365 struct_obj.zir_index = inst_map.get(struct_obj.zir_index) orelse {
3317 try file.deleted_decls.append(gpa, decl);3366 try file.deleted_decls.append(gpa, decl_index);
3318 continue;3367 continue;
3319 };3368 };
3320 }3369 }
33213370
3322 if (decl.getUnion()) |union_obj| {3371 if (decl.getUnion()) |union_obj| {
3323 union_obj.zir_index = inst_map.get(union_obj.zir_index) orelse {3372 union_obj.zir_index = inst_map.get(union_obj.zir_index) orelse {
3324 try file.deleted_decls.append(gpa, decl);3373 try file.deleted_decls.append(gpa, decl_index);
3325 continue;3374 continue;
3326 };3375 };
3327 }3376 }
33283377
3329 if (decl.getFunction()) |func| {3378 if (decl.getFunction()) |func| {
3330 func.zir_body_inst = inst_map.get(func.zir_body_inst) orelse {3379 func.zir_body_inst = inst_map.get(func.zir_body_inst) orelse {
3331 try file.deleted_decls.append(gpa, decl);3380 try file.deleted_decls.append(gpa, decl_index);
3332 continue;3381 continue;
3333 };3382 };
3334 }3383 }
...@@ -3485,10 +3534,12 @@ pub fn mapOldZirToNew(...@@ -3485,10 +3534,12 @@ pub fn mapOldZirToNew(
3485/// However the resolution status of the Type may not be fully resolved.3534/// However the resolution status of the Type may not be fully resolved.
3486/// For example an inferred error set is not resolved until after `analyzeFnBody`.3535/// For example an inferred error set is not resolved until after `analyzeFnBody`.
3487/// is called.3536/// is called.
3488pub fn ensureDeclAnalyzed(mod: *Module, decl: *Decl) SemaError!void {3537pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
3489 const tracy = trace(@src());3538 const tracy = trace(@src());
3490 defer tracy.end();3539 defer tracy.end();
34913540
3541 const decl = mod.declPtr(decl_index);
3542
3492 const subsequent_analysis = switch (decl.analysis) {3543 const subsequent_analysis = switch (decl.analysis) {
3493 .in_progress => unreachable,3544 .in_progress => unreachable,
34943545
...@@ -3507,15 +3558,16 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl: *Decl) SemaError!void {...@@ -3507,15 +3558,16 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl: *Decl) SemaError!void {
35073558
3508 // The exports this Decl performs will be re-discovered, so we remove them here3559 // The exports this Decl performs will be re-discovered, so we remove them here
3509 // prior to re-analysis.3560 // prior to re-analysis.
3510 mod.deleteDeclExports(decl);3561 mod.deleteDeclExports(decl_index);
3511 // Dependencies will be re-discovered, so we remove them here prior to re-analysis.3562 // Dependencies will be re-discovered, so we remove them here prior to re-analysis.
3512 for (decl.dependencies.keys()) |dep| {3563 for (decl.dependencies.keys()) |dep_index| {
3513 dep.removeDependant(decl);3564 const dep = mod.declPtr(dep_index);
3565 dep.removeDependant(decl_index);
3514 if (dep.dependants.count() == 0 and !dep.deletion_flag) {3566 if (dep.dependants.count() == 0 and !dep.deletion_flag) {
3515 log.debug("insert {*} ({s}) dependant {*} ({s}) into deletion set", .{3567 log.debug("insert {*} ({s}) dependant {*} ({s}) into deletion set", .{
3516 decl, decl.name, dep, dep.name,3568 decl, decl.name, dep, dep.name,
3517 });3569 });
3518 try mod.markDeclForDeletion(dep);3570 try mod.markDeclForDeletion(dep_index);
3519 }3571 }
3520 }3572 }
3521 decl.dependencies.clearRetainingCapacity();3573 decl.dependencies.clearRetainingCapacity();
...@@ -3530,7 +3582,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl: *Decl) SemaError!void {...@@ -3530,7 +3582,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl: *Decl) SemaError!void {
3530 decl_prog_node.activate();3582 decl_prog_node.activate();
3531 defer decl_prog_node.end();3583 defer decl_prog_node.end();
35323584
3533 const type_changed = mod.semaDecl(decl) catch |err| switch (err) {3585 const type_changed = mod.semaDecl(decl_index) catch |err| switch (err) {
3534 error.AnalysisFail => {3586 error.AnalysisFail => {
3535 if (decl.analysis == .in_progress) {3587 if (decl.analysis == .in_progress) {
3536 // If this decl caused the compile error, the analysis field would3588 // If this decl caused the compile error, the analysis field would
...@@ -3545,7 +3597,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl: *Decl) SemaError!void {...@@ -3545,7 +3597,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl: *Decl) SemaError!void {
3545 else => |e| {3597 else => |e| {
3546 decl.analysis = .sema_failure_retryable;3598 decl.analysis = .sema_failure_retryable;
3547 try mod.failed_decls.ensureUnusedCapacity(mod.gpa, 1);3599 try mod.failed_decls.ensureUnusedCapacity(mod.gpa, 1);
3548 mod.failed_decls.putAssumeCapacityNoClobber(decl, try ErrorMsg.create(3600 mod.failed_decls.putAssumeCapacityNoClobber(decl_index, try ErrorMsg.create(
3549 mod.gpa,3601 mod.gpa,
3550 decl.srcLoc(),3602 decl.srcLoc(),
3551 "unable to analyze: {s}",3603 "unable to analyze: {s}",
...@@ -3559,7 +3611,8 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl: *Decl) SemaError!void {...@@ -3559,7 +3611,8 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl: *Decl) SemaError!void {
3559 // We may need to chase the dependants and re-analyze them.3611 // We may need to chase the dependants and re-analyze them.
3560 // However, if the decl is a function, and the type is the same, we do not need to.3612 // However, if the decl is a function, and the type is the same, we do not need to.
3561 if (type_changed or decl.ty.zigTypeTag() != .Fn) {3613 if (type_changed or decl.ty.zigTypeTag() != .Fn) {
3562 for (decl.dependants.keys()) |dep| {3614 for (decl.dependants.keys()) |dep_index| {
3615 const dep = mod.declPtr(dep_index);
3563 switch (dep.analysis) {3616 switch (dep.analysis) {
3564 .unreferenced => unreachable,3617 .unreferenced => unreachable,
3565 .in_progress => continue, // already doing analysis, ok3618 .in_progress => continue, // already doing analysis, ok
...@@ -3573,7 +3626,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl: *Decl) SemaError!void {...@@ -3573,7 +3626,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl: *Decl) SemaError!void {
3573 .codegen_failure_retryable,3626 .codegen_failure_retryable,
3574 .complete,3627 .complete,
3575 => if (dep.generation != mod.generation) {3628 => if (dep.generation != mod.generation) {
3576 try mod.markOutdatedDecl(dep);3629 try mod.markOutdatedDecl(dep_index);
3577 },3630 },
3578 }3631 }
3579 }3632 }
...@@ -3585,7 +3638,10 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {...@@ -3585,7 +3638,10 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {
3585 const tracy = trace(@src());3638 const tracy = trace(@src());
3586 defer tracy.end();3639 defer tracy.end();
35873640
3588 switch (func.owner_decl.analysis) {3641 const decl_index = func.owner_decl;
3642 const decl = mod.declPtr(decl_index);
3643
3644 switch (decl.analysis) {
3589 .unreferenced => unreachable,3645 .unreferenced => unreachable,
3590 .in_progress => unreachable,3646 .in_progress => unreachable,
3591 .outdated => unreachable,3647 .outdated => unreachable,
...@@ -3607,13 +3663,12 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {...@@ -3607,13 +3663,12 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {
3607 }3663 }
36083664
3609 const gpa = mod.gpa;3665 const gpa = mod.gpa;
3610 const decl = func.owner_decl;
36113666
3612 var tmp_arena = std.heap.ArenaAllocator.init(gpa);3667 var tmp_arena = std.heap.ArenaAllocator.init(gpa);
3613 defer tmp_arena.deinit();3668 defer tmp_arena.deinit();
3614 const sema_arena = tmp_arena.allocator();3669 const sema_arena = tmp_arena.allocator();
36153670
3616 var air = mod.analyzeFnBody(decl, func, sema_arena) catch |err| switch (err) {3671 var air = mod.analyzeFnBody(func, sema_arena) catch |err| switch (err) {
3617 error.AnalysisFail => {3672 error.AnalysisFail => {
3618 if (func.state == .in_progress) {3673 if (func.state == .in_progress) {
3619 // If this decl caused the compile error, the analysis field would3674 // If this decl caused the compile error, the analysis field would
...@@ -3635,7 +3690,7 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {...@@ -3635,7 +3690,7 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {
36353690
3636 if (builtin.mode == .Debug and mod.comp.verbose_air) {3691 if (builtin.mode == .Debug and mod.comp.verbose_air) {
3637 std.debug.print("# Begin Function AIR: {s}:\n", .{decl.name});3692 std.debug.print("# Begin Function AIR: {s}:\n", .{decl.name});
3638 @import("print_air.zig").dump(gpa, air, liveness);3693 @import("print_air.zig").dump(mod, air, liveness);
3639 std.debug.print("# End Function AIR: {s}\n\n", .{decl.name});3694 std.debug.print("# End Function AIR: {s}\n\n", .{decl.name});
3640 }3695 }
36413696
...@@ -3647,7 +3702,7 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {...@@ -3647,7 +3702,7 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {
3647 },3702 },
3648 else => {3703 else => {
3649 try mod.failed_decls.ensureUnusedCapacity(gpa, 1);3704 try mod.failed_decls.ensureUnusedCapacity(gpa, 1);
3650 mod.failed_decls.putAssumeCapacityNoClobber(decl, try Module.ErrorMsg.create(3705 mod.failed_decls.putAssumeCapacityNoClobber(decl_index, try Module.ErrorMsg.create(
3651 gpa,3706 gpa,
3652 decl.srcLoc(),3707 decl.srcLoc(),
3653 "unable to codegen: {s}",3708 "unable to codegen: {s}",
...@@ -3668,7 +3723,9 @@ pub fn updateEmbedFile(mod: *Module, embed_file: *EmbedFile) SemaError!void {...@@ -3668,7 +3723,9 @@ pub fn updateEmbedFile(mod: *Module, embed_file: *EmbedFile) SemaError!void {
36683723
3669 // TODO we can potentially relax this if we store some more information along3724 // TODO we can potentially relax this if we store some more information along
3670 // with decl dependency edges3725 // with decl dependency edges
3671 for (embed_file.owner_decl.dependants.keys()) |dep| {3726 const owner_decl = mod.declPtr(embed_file.owner_decl);
3727 for (owner_decl.dependants.keys()) |dep_index| {
3728 const dep = mod.declPtr(dep_index);
3672 switch (dep.analysis) {3729 switch (dep.analysis) {
3673 .unreferenced => unreachable,3730 .unreferenced => unreachable,
3674 .in_progress => continue, // already doing analysis, ok3731 .in_progress => continue, // already doing analysis, ok
...@@ -3682,7 +3739,7 @@ pub fn updateEmbedFile(mod: *Module, embed_file: *EmbedFile) SemaError!void {...@@ -3682,7 +3739,7 @@ pub fn updateEmbedFile(mod: *Module, embed_file: *EmbedFile) SemaError!void {
3682 .codegen_failure_retryable,3739 .codegen_failure_retryable,
3683 .complete,3740 .complete,
3684 => if (dep.generation != mod.generation) {3741 => if (dep.generation != mod.generation) {
3685 try mod.markOutdatedDecl(dep);3742 try mod.markOutdatedDecl(dep_index);
3686 },3743 },
3687 }3744 }
3688 }3745 }
...@@ -3699,7 +3756,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -3699,7 +3756,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
3699 const tracy = trace(@src());3756 const tracy = trace(@src());
3700 defer tracy.end();3757 defer tracy.end();
37013758
3702 if (file.root_decl != null) return;3759 if (file.root_decl != .none) return;
37033760
3704 const gpa = mod.gpa;3761 const gpa = mod.gpa;
3705 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);3762 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
...@@ -3724,10 +3781,11 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -3724,10 +3781,11 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
3724 .file_scope = file,3781 .file_scope = file,
3725 },3782 },
3726 };3783 };
3727 const decl_name = try file.fullyQualifiedNameZ(gpa);3784 const new_decl_index = try mod.allocateNewDecl(&struct_obj.namespace, 0, null);
3728 const new_decl = try mod.allocateNewDecl(decl_name, &struct_obj.namespace, 0, null);3785 const new_decl = mod.declPtr(new_decl_index);
3729 file.root_decl = new_decl;3786 file.root_decl = new_decl_index.toOptional();
3730 struct_obj.owner_decl = new_decl;3787 struct_obj.owner_decl = new_decl_index;
3788 new_decl.name = try file.fullyQualifiedNameZ(gpa);
3731 new_decl.src_line = 0;3789 new_decl.src_line = 0;
3732 new_decl.is_pub = true;3790 new_decl.is_pub = true;
3733 new_decl.is_exported = false;3791 new_decl.is_exported = false;
...@@ -3757,6 +3815,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -3757,6 +3815,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
3757 .perm_arena = new_decl_arena_allocator,3815 .perm_arena = new_decl_arena_allocator,
3758 .code = file.zir,3816 .code = file.zir,
3759 .owner_decl = new_decl,3817 .owner_decl = new_decl,
3818 .owner_decl_index = new_decl_index,
3760 .func = null,3819 .func = null,
3761 .fn_ret_ty = Type.void,3820 .fn_ret_ty = Type.void,
3762 .owner_func = null,3821 .owner_func = null,
...@@ -3769,7 +3828,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -3769,7 +3828,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
3769 var block_scope: Sema.Block = .{3828 var block_scope: Sema.Block = .{
3770 .parent = null,3829 .parent = null,
3771 .sema = &sema,3830 .sema = &sema,
3772 .src_decl = new_decl,3831 .src_decl = new_decl_index,
3773 .namespace = &struct_obj.namespace,3832 .namespace = &struct_obj.namespace,
3774 .wip_capture_scope = wip_captures.scope,3833 .wip_capture_scope = wip_captures.scope,
3775 .instructions = .{},3834 .instructions = .{},
...@@ -3808,10 +3867,12 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -3808,10 +3867,12 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
3808/// Returns `true` if the Decl type changed.3867/// Returns `true` if the Decl type changed.
3809/// Returns `true` if this is the first time analyzing the Decl.3868/// Returns `true` if this is the first time analyzing the Decl.
3810/// Returns `false` otherwise.3869/// Returns `false` otherwise.
3811fn semaDecl(mod: *Module, decl: *Decl) !bool {3870fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
3812 const tracy = trace(@src());3871 const tracy = trace(@src());
3813 defer tracy.end();3872 defer tracy.end();
38143873
3874 const decl = mod.declPtr(decl_index);
3875
3815 if (decl.getFileScope().status != .success_zir) {3876 if (decl.getFileScope().status != .success_zir) {
3816 return error.AnalysisFail;3877 return error.AnalysisFail;
3817 }3878 }
...@@ -3838,13 +3899,14 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3838,13 +3899,14 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3838 .perm_arena = decl_arena_allocator,3899 .perm_arena = decl_arena_allocator,
3839 .code = zir,3900 .code = zir,
3840 .owner_decl = decl,3901 .owner_decl = decl,
3902 .owner_decl_index = decl_index,
3841 .func = null,3903 .func = null,
3842 .fn_ret_ty = Type.void,3904 .fn_ret_ty = Type.void,
3843 .owner_func = null,3905 .owner_func = null,
3844 };3906 };
3845 defer sema.deinit();3907 defer sema.deinit();
38463908
3847 if (decl.isRoot()) {3909 if (mod.declIsRoot(decl_index)) {
3848 log.debug("semaDecl root {*} ({s})", .{ decl, decl.name });3910 log.debug("semaDecl root {*} ({s})", .{ decl, decl.name });
3849 const main_struct_inst = Zir.main_struct_inst;3911 const main_struct_inst = Zir.main_struct_inst;
3850 const struct_obj = decl.getStruct().?;3912 const struct_obj = decl.getStruct().?;
...@@ -3864,7 +3926,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3864,7 +3926,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3864 var block_scope: Sema.Block = .{3926 var block_scope: Sema.Block = .{
3865 .parent = null,3927 .parent = null,
3866 .sema = &sema,3928 .sema = &sema,
3867 .src_decl = decl,3929 .src_decl = decl_index,
3868 .namespace = decl.src_namespace,3930 .namespace = decl.src_namespace,
3869 .wip_capture_scope = wip_captures.scope,3931 .wip_capture_scope = wip_captures.scope,
3870 .instructions = .{},3932 .instructions = .{},
...@@ -3922,15 +3984,15 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3922,15 +3984,15 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3922 const decl_arena_state = try decl_arena_allocator.create(std.heap.ArenaAllocator.State);3984 const decl_arena_state = try decl_arena_allocator.create(std.heap.ArenaAllocator.State);
39233985
3924 if (decl.is_usingnamespace) {3986 if (decl.is_usingnamespace) {
3925 if (!decl_tv.ty.eql(Type.type, target)) {3987 if (!decl_tv.ty.eql(Type.type, mod)) {
3926 return sema.fail(&block_scope, src, "expected type, found {}", .{3988 return sema.fail(&block_scope, src, "expected type, found {}", .{
3927 decl_tv.ty.fmt(target),3989 decl_tv.ty.fmt(mod),
3928 });3990 });
3929 }3991 }
3930 var buffer: Value.ToTypeBuffer = undefined;3992 var buffer: Value.ToTypeBuffer = undefined;
3931 const ty = try decl_tv.val.toType(&buffer).copy(decl_arena_allocator);3993 const ty = try decl_tv.val.toType(&buffer).copy(decl_arena_allocator);
3932 if (ty.getNamespace() == null) {3994 if (ty.getNamespace() == null) {
3933 return sema.fail(&block_scope, src, "type {} has no namespace", .{ty.fmt(target)});3995 return sema.fail(&block_scope, src, "type {} has no namespace", .{ty.fmt(mod)});
3934 }3996 }
39353997
3936 decl.ty = Type.type;3998 decl.ty = Type.type;
...@@ -3949,7 +4011,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3949,7 +4011,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
39494011
3950 if (decl_tv.val.castTag(.function)) |fn_payload| {4012 if (decl_tv.val.castTag(.function)) |fn_payload| {
3951 const func = fn_payload.data;4013 const func = fn_payload.data;
3952 const owns_tv = func.owner_decl == decl;4014 const owns_tv = func.owner_decl == decl_index;
3953 if (owns_tv) {4015 if (owns_tv) {
3954 var prev_type_has_bits = false;4016 var prev_type_has_bits = false;
3955 var prev_is_inline = false;4017 var prev_is_inline = false;
...@@ -3957,7 +4019,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3957,7 +4019,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
39574019
3958 if (decl.has_tv) {4020 if (decl.has_tv) {
3959 prev_type_has_bits = decl.ty.isFnOrHasRuntimeBits();4021 prev_type_has_bits = decl.ty.isFnOrHasRuntimeBits();
3960 type_changed = !decl.ty.eql(decl_tv.ty, target);4022 type_changed = !decl.ty.eql(decl_tv.ty, mod);
3961 if (decl.getFunction()) |prev_func| {4023 if (decl.getFunction()) |prev_func| {
3962 prev_is_inline = prev_func.state == .inline_only;4024 prev_is_inline = prev_func.state == .inline_only;
3963 }4025 }
...@@ -3982,13 +4044,13 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3982,13 +4044,13 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3982 // We don't fully codegen the decl until later, but we do need to reserve a global4044 // We don't fully codegen the decl until later, but we do need to reserve a global
3983 // offset table index for it. This allows us to codegen decls out of dependency4045 // offset table index for it. This allows us to codegen decls out of dependency
3984 // order, increasing how many computations can be done in parallel.4046 // order, increasing how many computations can be done in parallel.
3985 try mod.comp.bin_file.allocateDeclIndexes(decl);4047 try mod.comp.bin_file.allocateDeclIndexes(decl_index);
3986 try mod.comp.work_queue.writeItem(.{ .codegen_func = func });4048 try mod.comp.work_queue.writeItem(.{ .codegen_func = func });
3987 if (type_changed and mod.emit_h != null) {4049 if (type_changed and mod.emit_h != null) {
3988 try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl });4050 try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl_index });
3989 }4051 }
3990 } else if (!prev_is_inline and prev_type_has_bits) {4052 } else if (!prev_is_inline and prev_type_has_bits) {
3991 mod.comp.bin_file.freeDecl(decl);4053 mod.comp.bin_file.freeDecl(decl_index);
3992 }4054 }
39934055
3994 const is_inline = decl.ty.fnCallingConvention() == .Inline;4056 const is_inline = decl.ty.fnCallingConvention() == .Inline;
...@@ -3999,14 +4061,14 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3999,14 +4061,14 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3999 }4061 }
4000 // The scope needs to have the decl in it.4062 // The scope needs to have the decl in it.
4001 const options: std.builtin.ExportOptions = .{ .name = mem.sliceTo(decl.name, 0) };4063 const options: std.builtin.ExportOptions = .{ .name = mem.sliceTo(decl.name, 0) };
4002 try sema.analyzeExport(&block_scope, export_src, options, decl);4064 try sema.analyzeExport(&block_scope, export_src, options, decl_index);
4003 }4065 }
4004 return type_changed or is_inline != prev_is_inline;4066 return type_changed or is_inline != prev_is_inline;
4005 }4067 }
4006 }4068 }
4007 var type_changed = true;4069 var type_changed = true;
4008 if (decl.has_tv) {4070 if (decl.has_tv) {
4009 type_changed = !decl.ty.eql(decl_tv.ty, target);4071 type_changed = !decl.ty.eql(decl_tv.ty, mod);
4010 decl.clearValues(gpa);4072 decl.clearValues(gpa);
4011 }4073 }
40124074
...@@ -4016,7 +4078,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -4016,7 +4078,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
4016 switch (decl_tv.val.tag()) {4078 switch (decl_tv.val.tag()) {
4017 .variable => {4079 .variable => {
4018 const variable = decl_tv.val.castTag(.variable).?.data;4080 const variable = decl_tv.val.castTag(.variable).?.data;
4019 if (variable.owner_decl == decl) {4081 if (variable.owner_decl == decl_index) {
4020 decl.owns_tv = true;4082 decl.owns_tv = true;
4021 queue_linker_work = true;4083 queue_linker_work = true;
40224084
...@@ -4026,7 +4088,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -4026,7 +4088,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
4026 },4088 },
4027 .extern_fn => {4089 .extern_fn => {
4028 const extern_fn = decl_tv.val.castTag(.extern_fn).?.data;4090 const extern_fn = decl_tv.val.castTag(.extern_fn).?.data;
4029 if (extern_fn.owner_decl == decl) {4091 if (extern_fn.owner_decl == decl_index) {
4030 decl.owns_tv = true;4092 decl.owns_tv = true;
4031 queue_linker_work = true;4093 queue_linker_work = true;
4032 is_extern = true;4094 is_extern = true;
...@@ -4065,11 +4127,11 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -4065,11 +4127,11 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
4065 // codegen backend wants full access to the Decl Type.4127 // codegen backend wants full access to the Decl Type.
4066 try sema.resolveTypeFully(&block_scope, src, decl.ty);4128 try sema.resolveTypeFully(&block_scope, src, decl.ty);
40674129
4068 try mod.comp.bin_file.allocateDeclIndexes(decl);4130 try mod.comp.bin_file.allocateDeclIndexes(decl_index);
4069 try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl });4131 try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
40704132
4071 if (type_changed and mod.emit_h != null) {4133 if (type_changed and mod.emit_h != null) {
4072 try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl });4134 try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl_index });
4073 }4135 }
4074 }4136 }
40754137
...@@ -4077,15 +4139,18 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -4077,15 +4139,18 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
4077 const export_src = src; // TODO point to the export token4139 const export_src = src; // TODO point to the export token
4078 // The scope needs to have the decl in it.4140 // The scope needs to have the decl in it.
4079 const options: std.builtin.ExportOptions = .{ .name = mem.sliceTo(decl.name, 0) };4141 const options: std.builtin.ExportOptions = .{ .name = mem.sliceTo(decl.name, 0) };
4080 try sema.analyzeExport(&block_scope, export_src, options, decl);4142 try sema.analyzeExport(&block_scope, export_src, options, decl_index);
4081 }4143 }
40824144
4083 return type_changed;4145 return type_changed;
4084}4146}
40854147
4086/// Returns the depender's index of the dependee.4148/// Returns the depender's index of the dependee.
4087pub fn declareDeclDependency(mod: *Module, depender: *Decl, dependee: *Decl) !void {4149pub fn declareDeclDependency(mod: *Module, depender_index: Decl.Index, dependee_index: Decl.Index) !void {
4088 if (depender == dependee) return;4150 if (depender_index == dependee_index) return;
4151
4152 const depender = mod.declPtr(depender_index);
4153 const dependee = mod.declPtr(dependee_index);
40894154
4090 log.debug("{*} ({s}) depends on {*} ({s})", .{4155 log.debug("{*} ({s}) depends on {*} ({s})", .{
4091 depender, depender.name, dependee, dependee.name,4156 depender, depender.name, dependee, dependee.name,
...@@ -4096,11 +4161,11 @@ pub fn declareDeclDependency(mod: *Module, depender: *Decl, dependee: *Decl) !vo...@@ -4096,11 +4161,11 @@ pub fn declareDeclDependency(mod: *Module, depender: *Decl, dependee: *Decl) !vo
40964161
4097 if (dependee.deletion_flag) {4162 if (dependee.deletion_flag) {
4098 dependee.deletion_flag = false;4163 dependee.deletion_flag = false;
4099 assert(mod.deletion_set.swapRemove(dependee));4164 assert(mod.deletion_set.swapRemove(dependee_index));
4100 }4165 }
41014166
4102 dependee.dependants.putAssumeCapacity(depender, {});4167 dependee.dependants.putAssumeCapacity(depender_index, {});
4103 depender.dependencies.putAssumeCapacity(dependee, {});4168 depender.dependencies.putAssumeCapacity(dependee_index, {});
4104}4169}
41054170
4106pub const ImportFileResult = struct {4171pub const ImportFileResult = struct {
...@@ -4146,7 +4211,7 @@ pub fn importPkg(mod: *Module, pkg: *Package) !ImportFileResult {...@@ -4146,7 +4211,7 @@ pub fn importPkg(mod: *Module, pkg: *Package) !ImportFileResult {
4146 .zir = undefined,4211 .zir = undefined,
4147 .status = .never_loaded,4212 .status = .never_loaded,
4148 .pkg = pkg,4213 .pkg = pkg,
4149 .root_decl = null,4214 .root_decl = .none,
4150 };4215 };
4151 return ImportFileResult{4216 return ImportFileResult{
4152 .file = new_file,4217 .file = new_file,
...@@ -4214,7 +4279,7 @@ pub fn importFile(...@@ -4214,7 +4279,7 @@ pub fn importFile(
4214 .zir = undefined,4279 .zir = undefined,
4215 .status = .never_loaded,4280 .status = .never_loaded,
4216 .pkg = cur_file.pkg,4281 .pkg = cur_file.pkg,
4217 .root_decl = null,4282 .root_decl = .none,
4218 };4283 };
4219 return ImportFileResult{4284 return ImportFileResult{
4220 .file = new_file,4285 .file = new_file,
...@@ -4388,8 +4453,8 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi...@@ -4388,8 +4453,8 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
4388 const line = iter.parent_decl.relativeToLine(line_off);4453 const line = iter.parent_decl.relativeToLine(line_off);
4389 const decl_name_index = zir.extra[decl_sub_index + 5];4454 const decl_name_index = zir.extra[decl_sub_index + 5];
4390 const decl_doccomment_index = zir.extra[decl_sub_index + 7];4455 const decl_doccomment_index = zir.extra[decl_sub_index + 7];
4391 const decl_index = zir.extra[decl_sub_index + 6];4456 const decl_zir_index = zir.extra[decl_sub_index + 6];
4392 const decl_block_inst_data = zir.instructions.items(.data)[decl_index].pl_node;4457 const decl_block_inst_data = zir.instructions.items(.data)[decl_zir_index].pl_node;
4393 const decl_node = iter.parent_decl.relativeToNodeIndex(decl_block_inst_data.src_node);4458 const decl_node = iter.parent_decl.relativeToNodeIndex(decl_block_inst_data.src_node);
43944459
4395 // Every Decl needs a name.4460 // Every Decl needs a name.
...@@ -4432,15 +4497,22 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi...@@ -4432,15 +4497,22 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
4432 if (is_usingnamespace) try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1);4497 if (is_usingnamespace) try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1);
44334498
4434 // We create a Decl for it regardless of analysis status.4499 // We create a Decl for it regardless of analysis status.
4435 const gop = try namespace.decls.getOrPutAdapted(gpa, @as([]const u8, mem.sliceTo(decl_name, 0)), DeclAdapter{});4500 const gop = try namespace.decls.getOrPutContextAdapted(
4501 gpa,
4502 @as([]const u8, mem.sliceTo(decl_name, 0)),
4503 DeclAdapter{ .mod = mod },
4504 Namespace.DeclContext{ .module = mod },
4505 );
4436 if (!gop.found_existing) {4506 if (!gop.found_existing) {
4437 const new_decl = try mod.allocateNewDecl(decl_name, namespace, decl_node, iter.parent_decl.src_scope);4507 const new_decl_index = try mod.allocateNewDecl(namespace, decl_node, iter.parent_decl.src_scope);
4508 const new_decl = mod.declPtr(new_decl_index);
4509 new_decl.name = decl_name;
4438 if (is_usingnamespace) {4510 if (is_usingnamespace) {
4439 namespace.usingnamespace_set.putAssumeCapacity(new_decl, is_pub);4511 namespace.usingnamespace_set.putAssumeCapacity(new_decl_index, is_pub);
4440 }4512 }
4441 log.debug("scan new {*} ({s}) into {*}", .{ new_decl, decl_name, namespace });4513 log.debug("scan new {*} ({s}) into {*}", .{ new_decl, decl_name, namespace });
4442 new_decl.src_line = line;4514 new_decl.src_line = line;
4443 gop.key_ptr.* = new_decl;4515 gop.key_ptr.* = new_decl_index;
4444 // Exported decls, comptime decls, usingnamespace decls, and4516 // Exported decls, comptime decls, usingnamespace decls, and
4445 // test decls if in test mode, get analyzed.4517 // test decls if in test mode, get analyzed.
4446 const decl_pkg = namespace.file_scope.pkg;4518 const decl_pkg = namespace.file_scope.pkg;
...@@ -4451,7 +4523,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi...@@ -4451,7 +4523,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
4451 // the test name filter.4523 // the test name filter.
4452 if (!mod.comp.bin_file.options.is_test) break :blk false;4524 if (!mod.comp.bin_file.options.is_test) break :blk false;
4453 if (decl_pkg != mod.main_pkg) break :blk false;4525 if (decl_pkg != mod.main_pkg) break :blk false;
4454 try mod.test_functions.put(gpa, new_decl, {});4526 try mod.test_functions.put(gpa, new_decl_index, {});
4455 break :blk true;4527 break :blk true;
4456 },4528 },
4457 else => blk: {4529 else => blk: {
...@@ -4459,12 +4531,12 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi...@@ -4459,12 +4531,12 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
4459 if (!mod.comp.bin_file.options.is_test) break :blk false;4531 if (!mod.comp.bin_file.options.is_test) break :blk false;
4460 if (decl_pkg != mod.main_pkg) break :blk false;4532 if (decl_pkg != mod.main_pkg) break :blk false;
4461 // TODO check the name against --test-filter4533 // TODO check the name against --test-filter
4462 try mod.test_functions.put(gpa, new_decl, {});4534 try mod.test_functions.put(gpa, new_decl_index, {});
4463 break :blk true;4535 break :blk true;
4464 },4536 },
4465 };4537 };
4466 if (want_analysis) {4538 if (want_analysis) {
4467 mod.comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl });4539 mod.comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl_index });
4468 }4540 }
4469 new_decl.is_pub = is_pub;4541 new_decl.is_pub = is_pub;
4470 new_decl.is_exported = is_exported;4542 new_decl.is_exported = is_exported;
...@@ -4476,7 +4548,8 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi...@@ -4476,7 +4548,8 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
4476 return;4548 return;
4477 }4549 }
4478 gpa.free(decl_name);4550 gpa.free(decl_name);
4479 const decl = gop.key_ptr.*;4551 const decl_index = gop.key_ptr.*;
4552 const decl = mod.declPtr(decl_index);
4480 log.debug("scan existing {*} ({s}) of {*}", .{ decl, decl.name, namespace });4553 log.debug("scan existing {*} ({s}) of {*}", .{ decl, decl.name, namespace });
4481 // Update the AST node of the decl; even if its contents are unchanged, it may4554 // Update the AST node of the decl; even if its contents are unchanged, it may
4482 // have been re-ordered.4555 // have been re-ordered.
...@@ -4497,17 +4570,17 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi...@@ -4497,17 +4570,17 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
4497 .elf => if (decl.fn_link.elf.len != 0) {4570 .elf => if (decl.fn_link.elf.len != 0) {
4498 // TODO Look into detecting when this would be unnecessary by storing enough state4571 // TODO Look into detecting when this would be unnecessary by storing enough state
4499 // in `Decl` to notice that the line number did not change.4572 // in `Decl` to notice that the line number did not change.
4500 mod.comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl });4573 mod.comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index });
4501 },4574 },
4502 .macho => if (decl.fn_link.macho.len != 0) {4575 .macho => if (decl.fn_link.macho.len != 0) {
4503 // TODO Look into detecting when this would be unnecessary by storing enough state4576 // TODO Look into detecting when this would be unnecessary by storing enough state
4504 // in `Decl` to notice that the line number did not change.4577 // in `Decl` to notice that the line number did not change.
4505 mod.comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl });4578 mod.comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index });
4506 },4579 },
4507 .plan9 => {4580 .plan9 => {
4508 // TODO Look into detecting when this would be unnecessary by storing enough state4581 // TODO Look into detecting when this would be unnecessary by storing enough state
4509 // in `Decl` to notice that the line number did not change.4582 // in `Decl` to notice that the line number did not change.
4510 mod.comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl });4583 mod.comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index });
4511 },4584 },
4512 .c, .wasm, .spirv, .nvptx => {},4585 .c, .wasm, .spirv, .nvptx => {},
4513 }4586 }
...@@ -4517,25 +4590,27 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi...@@ -4517,25 +4590,27 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
4517/// Make it as if the semantic analysis for this Decl never happened.4590/// Make it as if the semantic analysis for this Decl never happened.
4518pub fn clearDecl(4591pub fn clearDecl(
4519 mod: *Module,4592 mod: *Module,
4520 decl: *Decl,4593 decl_index: Decl.Index,
4521 outdated_decls: ?*std.AutoArrayHashMap(*Decl, void),4594 outdated_decls: ?*std.AutoArrayHashMap(Decl.Index, void),
4522) Allocator.Error!void {4595) Allocator.Error!void {
4523 const tracy = trace(@src());4596 const tracy = trace(@src());
4524 defer tracy.end();4597 defer tracy.end();
45254598
4599 const decl = mod.declPtr(decl_index);
4526 log.debug("clearing {*} ({s})", .{ decl, decl.name });4600 log.debug("clearing {*} ({s})", .{ decl, decl.name });
45274601
4528 const gpa = mod.gpa;4602 const gpa = mod.gpa;
4529 try mod.deletion_set.ensureUnusedCapacity(gpa, decl.dependencies.count());4603 try mod.deletion_set.ensureUnusedCapacity(gpa, decl.dependencies.count());
45304604
4531 if (outdated_decls) |map| {4605 if (outdated_decls) |map| {
4532 _ = map.swapRemove(decl);4606 _ = map.swapRemove(decl_index);
4533 try map.ensureUnusedCapacity(decl.dependants.count());4607 try map.ensureUnusedCapacity(decl.dependants.count());
4534 }4608 }
45354609
4536 // Remove itself from its dependencies.4610 // Remove itself from its dependencies.
4537 for (decl.dependencies.keys()) |dep| {4611 for (decl.dependencies.keys()) |dep_index| {
4538 dep.removeDependant(decl);4612 const dep = mod.declPtr(dep_index);
4613 dep.removeDependant(decl_index);
4539 if (dep.dependants.count() == 0 and !dep.deletion_flag) {4614 if (dep.dependants.count() == 0 and !dep.deletion_flag) {
4540 log.debug("insert {*} ({s}) dependant {*} ({s}) into deletion set", .{4615 log.debug("insert {*} ({s}) dependant {*} ({s}) into deletion set", .{
4541 decl, decl.name, dep, dep.name,4616 decl, decl.name, dep, dep.name,
...@@ -4543,35 +4618,36 @@ pub fn clearDecl(...@@ -4543,35 +4618,36 @@ pub fn clearDecl(
4543 // We don't recursively perform a deletion here, because during the update,4618 // We don't recursively perform a deletion here, because during the update,
4544 // another reference to it may turn up.4619 // another reference to it may turn up.
4545 dep.deletion_flag = true;4620 dep.deletion_flag = true;
4546 mod.deletion_set.putAssumeCapacity(dep, {});4621 mod.deletion_set.putAssumeCapacity(dep_index, {});
4547 }4622 }
4548 }4623 }
4549 decl.dependencies.clearRetainingCapacity();4624 decl.dependencies.clearRetainingCapacity();
45504625
4551 // Anything that depends on this deleted decl needs to be re-analyzed.4626 // Anything that depends on this deleted decl needs to be re-analyzed.
4552 for (decl.dependants.keys()) |dep| {4627 for (decl.dependants.keys()) |dep_index| {
4553 dep.removeDependency(decl);4628 const dep = mod.declPtr(dep_index);
4629 dep.removeDependency(decl_index);
4554 if (outdated_decls) |map| {4630 if (outdated_decls) |map| {
4555 map.putAssumeCapacity(dep, {});4631 map.putAssumeCapacity(dep_index, {});
4556 }4632 }
4557 }4633 }
4558 decl.dependants.clearRetainingCapacity();4634 decl.dependants.clearRetainingCapacity();
45594635
4560 if (mod.failed_decls.fetchSwapRemove(decl)) |kv| {4636 if (mod.failed_decls.fetchSwapRemove(decl_index)) |kv| {
4561 kv.value.destroy(gpa);4637 kv.value.destroy(gpa);
4562 }4638 }
4563 if (mod.emit_h) |emit_h| {4639 if (mod.emit_h) |emit_h| {
4564 if (emit_h.failed_decls.fetchSwapRemove(decl)) |kv| {4640 if (emit_h.failed_decls.fetchSwapRemove(decl_index)) |kv| {
4565 kv.value.destroy(gpa);4641 kv.value.destroy(gpa);
4566 }4642 }
4567 assert(emit_h.decl_table.swapRemove(decl));4643 assert(emit_h.decl_table.swapRemove(decl_index));
4568 }4644 }
4569 _ = mod.compile_log_decls.swapRemove(decl);4645 _ = mod.compile_log_decls.swapRemove(decl_index);
4570 mod.deleteDeclExports(decl);4646 mod.deleteDeclExports(decl_index);
45714647
4572 if (decl.has_tv) {4648 if (decl.has_tv) {
4573 if (decl.ty.isFnOrHasRuntimeBits()) {4649 if (decl.ty.isFnOrHasRuntimeBits()) {
4574 mod.comp.bin_file.freeDecl(decl);4650 mod.comp.bin_file.freeDecl(decl_index);
45754651
4576 // TODO instead of a union, put this memory trailing Decl objects,4652 // TODO instead of a union, put this memory trailing Decl objects,
4577 // and allow it to be variably sized.4653 // and allow it to be variably sized.
...@@ -4604,15 +4680,16 @@ pub fn clearDecl(...@@ -4604,15 +4680,16 @@ pub fn clearDecl(
46044680
4605 if (decl.deletion_flag) {4681 if (decl.deletion_flag) {
4606 decl.deletion_flag = false;4682 decl.deletion_flag = false;
4607 assert(mod.deletion_set.swapRemove(decl));4683 assert(mod.deletion_set.swapRemove(decl_index));
4608 }4684 }
46094685
4610 decl.analysis = .unreferenced;4686 decl.analysis = .unreferenced;
4611}4687}
46124688
4613/// This function is exclusively called for anonymous decls.4689/// This function is exclusively called for anonymous decls.
4614pub fn deleteUnusedDecl(mod: *Module, decl: *Decl) void {4690pub fn deleteUnusedDecl(mod: *Module, decl_index: Decl.Index) void {
4615 log.debug("deleteUnusedDecl {*} ({s})", .{ decl, decl.name });4691 const decl = mod.declPtr(decl_index);
4692 log.debug("deleteUnusedDecl {d} ({s})", .{ decl_index, decl.name });
46164693
4617 // TODO: remove `allocateDeclIndexes` and make the API that the linker backends4694 // TODO: remove `allocateDeclIndexes` and make the API that the linker backends
4618 // are required to notice the first time `updateDecl` happens and keep track4695 // are required to notice the first time `updateDecl` happens and keep track
...@@ -4626,55 +4703,58 @@ pub fn deleteUnusedDecl(mod: *Module, decl: *Decl) void {...@@ -4626,55 +4703,58 @@ pub fn deleteUnusedDecl(mod: *Module, decl: *Decl) void {
4626 .c => {}, // this linker backend has already migrated to the new API4703 .c => {}, // this linker backend has already migrated to the new API
4627 else => if (decl.has_tv) {4704 else => if (decl.has_tv) {
4628 if (decl.ty.isFnOrHasRuntimeBits()) {4705 if (decl.ty.isFnOrHasRuntimeBits()) {
4629 mod.comp.bin_file.freeDecl(decl);4706 mod.comp.bin_file.freeDecl(decl_index);
4630 }4707 }
4631 },4708 },
4632 }4709 }
46334710
4634 assert(!decl.isRoot());4711 assert(!mod.declIsRoot(decl_index));
4635 assert(decl.src_namespace.anon_decls.swapRemove(decl));4712 assert(decl.src_namespace.anon_decls.swapRemove(decl_index));
46364713
4637 const dependants = decl.dependants.keys();4714 const dependants = decl.dependants.keys();
4638 for (dependants) |dep| {4715 for (dependants) |dep| {
4639 dep.removeDependency(decl);4716 mod.declPtr(dep).removeDependency(decl_index);
4640 }4717 }
46414718
4642 for (decl.dependencies.keys()) |dep| {4719 for (decl.dependencies.keys()) |dep| {
4643 dep.removeDependant(decl);4720 mod.declPtr(dep).removeDependant(decl_index);
4644 }4721 }
4645 decl.destroy(mod);4722 mod.destroyDecl(decl_index);
4646}4723}
46474724
4648/// We don't perform a deletion here, because this Decl or another one4725/// We don't perform a deletion here, because this Decl or another one
4649/// may end up referencing it before the update is complete.4726/// may end up referencing it before the update is complete.
4650fn markDeclForDeletion(mod: *Module, decl: *Decl) !void {4727fn markDeclForDeletion(mod: *Module, decl_index: Decl.Index) !void {
4728 const decl = mod.declPtr(decl_index);
4651 decl.deletion_flag = true;4729 decl.deletion_flag = true;
4652 try mod.deletion_set.put(mod.gpa, decl, {});4730 try mod.deletion_set.put(mod.gpa, decl_index, {});
4653}4731}
46544732
4655/// Cancel the creation of an anon decl and delete any references to it.4733/// Cancel the creation of an anon decl and delete any references to it.
4656/// If other decls depend on this decl, they must be aborted first.4734/// If other decls depend on this decl, they must be aborted first.
4657pub fn abortAnonDecl(mod: *Module, decl: *Decl) void {4735pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void {
4736 const decl = mod.declPtr(decl_index);
4658 log.debug("abortAnonDecl {*} ({s})", .{ decl, decl.name });4737 log.debug("abortAnonDecl {*} ({s})", .{ decl, decl.name });
46594738
4660 assert(!decl.isRoot());4739 assert(!mod.declIsRoot(decl_index));
4661 assert(decl.src_namespace.anon_decls.swapRemove(decl));4740 assert(decl.src_namespace.anon_decls.swapRemove(decl_index));
46624741
4663 // An aborted decl must not have dependants -- they must have4742 // An aborted decl must not have dependants -- they must have
4664 // been aborted first and removed from this list.4743 // been aborted first and removed from this list.
4665 assert(decl.dependants.count() == 0);4744 assert(decl.dependants.count() == 0);
46664745
4667 for (decl.dependencies.keys()) |dep| {4746 for (decl.dependencies.keys()) |dep_index| {
4668 dep.removeDependant(decl);4747 const dep = mod.declPtr(dep_index);
4748 dep.removeDependant(decl_index);
4669 }4749 }
46704750
4671 decl.destroy(mod);4751 mod.destroyDecl(decl_index);
4672}4752}
46734753
4674/// Delete all the Export objects that are caused by this Decl. Re-analysis of4754/// Delete all the Export objects that are caused by this Decl. Re-analysis of
4675/// this Decl will cause them to be re-created (or not).4755/// this Decl will cause them to be re-created (or not).
4676fn deleteDeclExports(mod: *Module, decl: *Decl) void {4756fn deleteDeclExports(mod: *Module, decl_index: Decl.Index) void {
4677 const kv = mod.export_owners.fetchSwapRemove(decl) orelse return;4757 const kv = mod.export_owners.fetchSwapRemove(decl_index) orelse return;
46784758
4679 for (kv.value) |exp| {4759 for (kv.value) |exp| {
4680 if (mod.decl_exports.getPtr(exp.exported_decl)) |value_ptr| {4760 if (mod.decl_exports.getPtr(exp.exported_decl)) |value_ptr| {
...@@ -4683,7 +4763,7 @@ fn deleteDeclExports(mod: *Module, decl: *Decl) void {...@@ -4683,7 +4763,7 @@ fn deleteDeclExports(mod: *Module, decl: *Decl) void {
4683 var i: usize = 0;4763 var i: usize = 0;
4684 var new_len = list.len;4764 var new_len = list.len;
4685 while (i < new_len) {4765 while (i < new_len) {
4686 if (list[i].owner_decl == decl) {4766 if (list[i].owner_decl == decl_index) {
4687 mem.copyBackwards(*Export, list[i..], list[i + 1 .. new_len]);4767 mem.copyBackwards(*Export, list[i..], list[i + 1 .. new_len]);
4688 new_len -= 1;4768 new_len -= 1;
4689 } else {4769 } else {
...@@ -4713,11 +4793,13 @@ fn deleteDeclExports(mod: *Module, decl: *Decl) void {...@@ -4713,11 +4793,13 @@ fn deleteDeclExports(mod: *Module, decl: *Decl) void {
4713 mod.gpa.free(kv.value);4793 mod.gpa.free(kv.value);
4714}4794}
47154795
4716pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: Allocator) SemaError!Air {4796pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {
4717 const tracy = trace(@src());4797 const tracy = trace(@src());
4718 defer tracy.end();4798 defer tracy.end();
47194799
4720 const gpa = mod.gpa;4800 const gpa = mod.gpa;
4801 const decl_index = func.owner_decl;
4802 const decl = mod.declPtr(decl_index);
47214803
4722 // Use the Decl's arena for captured values.4804 // Use the Decl's arena for captured values.
4723 var decl_arena = decl.value_arena.?.promote(gpa);4805 var decl_arena = decl.value_arena.?.promote(gpa);
...@@ -4731,8 +4813,9 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: Allocator) Sem...@@ -4731,8 +4813,9 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: Allocator) Sem
4731 .perm_arena = decl_arena_allocator,4813 .perm_arena = decl_arena_allocator,
4732 .code = decl.getFileScope().zir,4814 .code = decl.getFileScope().zir,
4733 .owner_decl = decl,4815 .owner_decl = decl,
4816 .owner_decl_index = decl_index,
4734 .func = func,4817 .func = func,
4735 .fn_ret_ty = func.owner_decl.ty.fnReturnType(),4818 .fn_ret_ty = decl.ty.fnReturnType(),
4736 .owner_func = func,4819 .owner_func = func,
4737 };4820 };
4738 defer sema.deinit();4821 defer sema.deinit();
...@@ -4748,7 +4831,7 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: Allocator) Sem...@@ -4748,7 +4831,7 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: Allocator) Sem
4748 var inner_block: Sema.Block = .{4831 var inner_block: Sema.Block = .{
4749 .parent = null,4832 .parent = null,
4750 .sema = &sema,4833 .sema = &sema,
4751 .src_decl = decl,4834 .src_decl = decl_index,
4752 .namespace = decl.src_namespace,4835 .namespace = decl.src_namespace,
4753 .wip_capture_scope = wip_captures.scope,4836 .wip_capture_scope = wip_captures.scope,
4754 .instructions = .{},4837 .instructions = .{},
...@@ -4903,10 +4986,11 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: Allocator) Sem...@@ -4903,10 +4986,11 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: Allocator) Sem
4903 };4986 };
4904}4987}
49054988
4906fn markOutdatedDecl(mod: *Module, decl: *Decl) !void {4989fn markOutdatedDecl(mod: *Module, decl_index: Decl.Index) !void {
4990 const decl = mod.declPtr(decl_index);
4907 log.debug("mark outdated {*} ({s})", .{ decl, decl.name });4991 log.debug("mark outdated {*} ({s})", .{ decl, decl.name });
4908 try mod.comp.work_queue.writeItem(.{ .analyze_decl = decl });4992 try mod.comp.work_queue.writeItem(.{ .analyze_decl = decl_index });
4909 if (mod.failed_decls.fetchSwapRemove(decl)) |kv| {4993 if (mod.failed_decls.fetchSwapRemove(decl_index)) |kv| {
4910 kv.value.destroy(mod.gpa);4994 kv.value.destroy(mod.gpa);
4911 }4995 }
4912 if (decl.has_tv and decl.owns_tv) {4996 if (decl.has_tv and decl.owns_tv) {
...@@ -4916,33 +5000,43 @@ fn markOutdatedDecl(mod: *Module, decl: *Decl) !void {...@@ -4916,33 +5000,43 @@ fn markOutdatedDecl(mod: *Module, decl: *Decl) !void {
4916 }5000 }
4917 }5001 }
4918 if (mod.emit_h) |emit_h| {5002 if (mod.emit_h) |emit_h| {
4919 if (emit_h.failed_decls.fetchSwapRemove(decl)) |kv| {5003 if (emit_h.failed_decls.fetchSwapRemove(decl_index)) |kv| {
4920 kv.value.destroy(mod.gpa);5004 kv.value.destroy(mod.gpa);
4921 }5005 }
4922 }5006 }
4923 _ = mod.compile_log_decls.swapRemove(decl);5007 _ = mod.compile_log_decls.swapRemove(decl_index);
4924 decl.analysis = .outdated;5008 decl.analysis = .outdated;
4925}5009}
49265010
4927pub fn allocateNewDecl(5011pub fn allocateNewDecl(
4928 mod: *Module,5012 mod: *Module,
4929 name: [:0]const u8,
4930 namespace: *Namespace,5013 namespace: *Namespace,
4931 src_node: Ast.Node.Index,5014 src_node: Ast.Node.Index,
4932 src_scope: ?*CaptureScope,5015 src_scope: ?*CaptureScope,
4933) !*Decl {5016) !Decl.Index {
4934 // If we have emit-h then we must allocate a bigger structure to store the emit-h state.5017 const decl_and_index: struct {
4935 const new_decl: *Decl = if (mod.emit_h != null) blk: {5018 new_decl: *Decl,
4936 const parent_struct = try mod.gpa.create(DeclPlusEmitH);5019 decl_index: Decl.Index,
4937 parent_struct.* = .{5020 } = if (mod.decls_free_list.popOrNull()) |decl_index| d: {
4938 .emit_h = .{},5021 break :d .{
4939 .decl = undefined,5022 .new_decl = mod.declPtr(decl_index),
5023 .decl_index = decl_index,
5024 };
5025 } else d: {
5026 const decl = try mod.allocated_decls.addOne(mod.gpa);
5027 errdefer mod.allocated_decls.shrinkRetainingCapacity(mod.allocated_decls.len - 1);
5028 if (mod.emit_h) |mod_emit_h| {
5029 const decl_emit_h = try mod_emit_h.allocated_emit_h.addOne(mod.gpa);
5030 decl_emit_h.* = .{};
5031 }
5032 break :d .{
5033 .new_decl = decl,
5034 .decl_index = @intToEnum(Decl.Index, mod.allocated_decls.len - 1),
4940 };5035 };
4941 break :blk &parent_struct.decl;5036 };
4942 } else try mod.gpa.create(Decl);
49435037
4944 new_decl.* = .{5038 decl_and_index.new_decl.* = .{
4945 .name = name,5039 .name = undefined,
4946 .src_namespace = namespace,5040 .src_namespace = namespace,
4947 .src_node = src_node,5041 .src_node = src_node,
4948 .src_line = undefined,5042 .src_line = undefined,
...@@ -4986,7 +5080,7 @@ pub fn allocateNewDecl(...@@ -4986,7 +5080,7 @@ pub fn allocateNewDecl(
4986 .is_usingnamespace = false,5080 .is_usingnamespace = false,
4987 };5081 };
49885082
4989 return new_decl;5083 return decl_and_index.decl_index;
4990}5084}
49915085
4992/// Get error value for error tag `name`.5086/// Get error value for error tag `name`.
...@@ -5010,18 +5104,9 @@ pub fn getErrorValue(mod: *Module, name: []const u8) !std.StringHashMapUnmanaged...@@ -5010,18 +5104,9 @@ pub fn getErrorValue(mod: *Module, name: []const u8) !std.StringHashMapUnmanaged
5010 };5104 };
5011}5105}
50125106
5013/// Takes ownership of `name` even if it returns an error.5107pub fn createAnonymousDecl(mod: *Module, block: *Sema.Block, typed_value: TypedValue) !Decl.Index {
5014pub fn createAnonymousDeclNamed(5108 const src_decl = mod.declPtr(block.src_decl);
5015 mod: *Module,5109 return mod.createAnonymousDeclFromDecl(src_decl, block.namespace, block.wip_capture_scope, typed_value);
5016 block: *Sema.Block,
5017 typed_value: TypedValue,
5018 name: [:0]u8,
5019) !*Decl {
5020 return mod.createAnonymousDeclFromDeclNamed(block.src_decl, block.namespace, block.wip_capture_scope, typed_value, name);
5021}
5022
5023pub fn createAnonymousDecl(mod: *Module, block: *Sema.Block, typed_value: TypedValue) !*Decl {
5024 return mod.createAnonymousDeclFromDecl(block.src_decl, block.namespace, block.wip_capture_scope, typed_value);
5025}5110}
50265111
5027pub fn createAnonymousDeclFromDecl(5112pub fn createAnonymousDeclFromDecl(
...@@ -5030,30 +5115,31 @@ pub fn createAnonymousDeclFromDecl(...@@ -5030,30 +5115,31 @@ pub fn createAnonymousDeclFromDecl(
5030 namespace: *Namespace,5115 namespace: *Namespace,
5031 src_scope: ?*CaptureScope,5116 src_scope: ?*CaptureScope,
5032 tv: TypedValue,5117 tv: TypedValue,
5033) !*Decl {5118) !Decl.Index {
5034 const name_index = mod.getNextAnonNameIndex();5119 const new_decl_index = try mod.allocateNewDecl(namespace, src_decl.src_node, src_scope);
5120 errdefer mod.destroyDecl(new_decl_index);
5035 const name = try std.fmt.allocPrintZ(mod.gpa, "{s}__anon_{d}", .{5121 const name = try std.fmt.allocPrintZ(mod.gpa, "{s}__anon_{d}", .{
5036 src_decl.name, name_index,5122 src_decl.name, @enumToInt(new_decl_index),
5037 });5123 });
5038 return mod.createAnonymousDeclFromDeclNamed(src_decl, namespace, src_scope, tv, name);5124 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, tv, name);
5125 return new_decl_index;
5039}5126}
50405127
5041/// Takes ownership of `name` even if it returns an error.5128/// Takes ownership of `name` even if it returns an error.
5042pub fn createAnonymousDeclFromDeclNamed(5129pub fn initNewAnonDecl(
5043 mod: *Module,5130 mod: *Module,
5044 src_decl: *Decl,5131 new_decl_index: Decl.Index,
5132 src_line: u32,
5045 namespace: *Namespace,5133 namespace: *Namespace,
5046 src_scope: ?*CaptureScope,
5047 typed_value: TypedValue,5134 typed_value: TypedValue,
5048 name: [:0]u8,5135 name: [:0]u8,
5049) !*Decl {5136) !void {
5050 errdefer mod.gpa.free(name);5137 errdefer mod.gpa.free(name);
50515138
5052 try namespace.anon_decls.ensureUnusedCapacity(mod.gpa, 1);5139 const new_decl = mod.declPtr(new_decl_index);
50535140
5054 const new_decl = try mod.allocateNewDecl(name, namespace, src_decl.src_node, src_scope);5141 new_decl.name = name;
50555142 new_decl.src_line = src_line;
5056 new_decl.src_line = src_decl.src_line;
5057 new_decl.ty = typed_value.ty;5143 new_decl.ty = typed_value.ty;
5058 new_decl.val = typed_value.val;5144 new_decl.val = typed_value.val;
5059 new_decl.@"align" = 0;5145 new_decl.@"align" = 0;
...@@ -5062,22 +5148,16 @@ pub fn createAnonymousDeclFromDeclNamed(...@@ -5062,22 +5148,16 @@ pub fn createAnonymousDeclFromDeclNamed(
5062 new_decl.analysis = .complete;5148 new_decl.analysis = .complete;
5063 new_decl.generation = mod.generation;5149 new_decl.generation = mod.generation;
50645150
5065 namespace.anon_decls.putAssumeCapacityNoClobber(new_decl, {});5151 try namespace.anon_decls.putNoClobber(mod.gpa, new_decl_index, {});
50665152
5067 // The Decl starts off with alive=false and the codegen backend will set alive=true5153 // The Decl starts off with alive=false and the codegen backend will set alive=true
5068 // if the Decl is referenced by an instruction or another constant. Otherwise,5154 // if the Decl is referenced by an instruction or another constant. Otherwise,
5069 // the Decl will be garbage collected by the `codegen_decl` task instead of sent5155 // the Decl will be garbage collected by the `codegen_decl` task instead of sent
5070 // to the linker.5156 // to the linker.
5071 if (typed_value.ty.isFnOrHasRuntimeBits()) {5157 if (typed_value.ty.isFnOrHasRuntimeBits()) {
5072 try mod.comp.bin_file.allocateDeclIndexes(new_decl);5158 try mod.comp.bin_file.allocateDeclIndexes(new_decl_index);
5073 try mod.comp.anon_work_queue.writeItem(.{ .codegen_decl = new_decl });5159 try mod.comp.anon_work_queue.writeItem(.{ .codegen_decl = new_decl_index });
5074 }5160 }
5075
5076 return new_decl;
5077}
5078
5079pub fn getNextAnonNameIndex(mod: *Module) usize {
5080 return @atomicRmw(usize, &mod.next_anon_name_index, .Add, 1, .Monotonic);
5081}5161}
50825162
5083pub fn makeIntType(arena: Allocator, signedness: std.builtin.Signedness, bits: u16) !Type {5163pub fn makeIntType(arena: Allocator, signedness: std.builtin.Signedness, bits: u16) !Type {
...@@ -5339,12 +5419,12 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {...@@ -5339,12 +5419,12 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {
5339 // for the outdated decls, but we cannot queue up the tasks until after5419 // for the outdated decls, but we cannot queue up the tasks until after
5340 // we find out which ones have been deleted, otherwise there would be5420 // we find out which ones have been deleted, otherwise there would be
5341 // deleted Decl pointers in the work queue.5421 // deleted Decl pointers in the work queue.
5342 var outdated_decls = std.AutoArrayHashMap(*Decl, void).init(mod.gpa);5422 var outdated_decls = std.AutoArrayHashMap(Decl.Index, void).init(mod.gpa);
5343 defer outdated_decls.deinit();5423 defer outdated_decls.deinit();
5344 for (mod.import_table.values()) |file| {5424 for (mod.import_table.values()) |file| {
5345 try outdated_decls.ensureUnusedCapacity(file.outdated_decls.items.len);5425 try outdated_decls.ensureUnusedCapacity(file.outdated_decls.items.len);
5346 for (file.outdated_decls.items) |decl| {5426 for (file.outdated_decls.items) |decl_index| {
5347 outdated_decls.putAssumeCapacity(decl, {});5427 outdated_decls.putAssumeCapacity(decl_index, {});
5348 }5428 }
5349 file.outdated_decls.clearRetainingCapacity();5429 file.outdated_decls.clearRetainingCapacity();
53505430
...@@ -5356,15 +5436,16 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {...@@ -5356,15 +5436,16 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {
5356 // it may be both in this `deleted_decls` set, as well as in the5436 // it may be both in this `deleted_decls` set, as well as in the
5357 // `Module.deletion_set`. To avoid deleting it twice, we remove it from the5437 // `Module.deletion_set`. To avoid deleting it twice, we remove it from the
5358 // deletion set at this time.5438 // deletion set at this time.
5359 for (file.deleted_decls.items) |decl| {5439 for (file.deleted_decls.items) |decl_index| {
5440 const decl = mod.declPtr(decl_index);
5360 log.debug("deleted from source: {*} ({s})", .{ decl, decl.name });5441 log.debug("deleted from source: {*} ({s})", .{ decl, decl.name });
53615442
5362 // Remove from the namespace it resides in, preserving declaration order.5443 // Remove from the namespace it resides in, preserving declaration order.
5363 assert(decl.zir_decl_index != 0);5444 assert(decl.zir_decl_index != 0);
5364 _ = decl.src_namespace.decls.orderedRemoveAdapted(@as([]const u8, mem.sliceTo(decl.name, 0)), DeclAdapter{});5445 _ = decl.src_namespace.decls.orderedRemoveAdapted(@as([]const u8, mem.sliceTo(decl.name, 0)), DeclAdapter{ .mod = mod });
53655446
5366 try mod.clearDecl(decl, &outdated_decls);5447 try mod.clearDecl(decl_index, &outdated_decls);
5367 decl.destroy(mod);5448 mod.destroyDecl(decl_index);
5368 }5449 }
5369 file.deleted_decls.clearRetainingCapacity();5450 file.deleted_decls.clearRetainingCapacity();
5370 }5451 }
...@@ -5393,13 +5474,13 @@ pub fn processExports(mod: *Module) !void {...@@ -5393,13 +5474,13 @@ pub fn processExports(mod: *Module) !void {
5393 if (gop.found_existing) {5474 if (gop.found_existing) {
5394 new_export.status = .failed_retryable;5475 new_export.status = .failed_retryable;
5395 try mod.failed_exports.ensureUnusedCapacity(gpa, 1);5476 try mod.failed_exports.ensureUnusedCapacity(gpa, 1);
5396 const src_loc = new_export.getSrcLoc();5477 const src_loc = new_export.getSrcLoc(mod);
5397 const msg = try ErrorMsg.create(gpa, src_loc, "exported symbol collision: {s}", .{5478 const msg = try ErrorMsg.create(gpa, src_loc, "exported symbol collision: {s}", .{
5398 new_export.options.name,5479 new_export.options.name,
5399 });5480 });
5400 errdefer msg.destroy(gpa);5481 errdefer msg.destroy(gpa);
5401 const other_export = gop.value_ptr.*;5482 const other_export = gop.value_ptr.*;
5402 const other_src_loc = other_export.getSrcLoc();5483 const other_src_loc = other_export.getSrcLoc(mod);
5403 try mod.errNoteNonLazy(other_src_loc, msg, "other symbol here", .{});5484 try mod.errNoteNonLazy(other_src_loc, msg, "other symbol here", .{});
5404 mod.failed_exports.putAssumeCapacityNoClobber(new_export, msg);5485 mod.failed_exports.putAssumeCapacityNoClobber(new_export, msg);
5405 new_export.status = .failed;5486 new_export.status = .failed;
...@@ -5413,7 +5494,7 @@ pub fn processExports(mod: *Module) !void {...@@ -5413,7 +5494,7 @@ pub fn processExports(mod: *Module) !void {
5413 const new_export = exports[0];5494 const new_export = exports[0];
5414 new_export.status = .failed_retryable;5495 new_export.status = .failed_retryable;
5415 try mod.failed_exports.ensureUnusedCapacity(gpa, 1);5496 try mod.failed_exports.ensureUnusedCapacity(gpa, 1);
5416 const src_loc = new_export.getSrcLoc();5497 const src_loc = new_export.getSrcLoc(mod);
5417 const msg = try ErrorMsg.create(gpa, src_loc, "unable to export: {s}", .{5498 const msg = try ErrorMsg.create(gpa, src_loc, "unable to export: {s}", .{
5418 @errorName(err),5499 @errorName(err),
5419 });5500 });
...@@ -5427,12 +5508,14 @@ pub fn populateTestFunctions(mod: *Module) !void {...@@ -5427,12 +5508,14 @@ pub fn populateTestFunctions(mod: *Module) !void {
5427 const gpa = mod.gpa;5508 const gpa = mod.gpa;
5428 const builtin_pkg = mod.main_pkg.table.get("builtin").?;5509 const builtin_pkg = mod.main_pkg.table.get("builtin").?;
5429 const builtin_file = (mod.importPkg(builtin_pkg) catch unreachable).file;5510 const builtin_file = (mod.importPkg(builtin_pkg) catch unreachable).file;
5430 const builtin_namespace = builtin_file.root_decl.?.src_namespace;5511 const root_decl = mod.declPtr(builtin_file.root_decl.unwrap().?);
5431 const decl = builtin_namespace.decls.getKeyAdapted(@as([]const u8, "test_functions"), DeclAdapter{}).?;5512 const builtin_namespace = root_decl.src_namespace;
5513 const decl_index = builtin_namespace.decls.getKeyAdapted(@as([]const u8, "test_functions"), DeclAdapter{ .mod = mod }).?;
5514 const decl = mod.declPtr(decl_index);
5432 var buf: Type.SlicePtrFieldTypeBuffer = undefined;5515 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
5433 const tmp_test_fn_ty = decl.ty.slicePtrFieldType(&buf).elemType();5516 const tmp_test_fn_ty = decl.ty.slicePtrFieldType(&buf).elemType();
54345517
5435 const array_decl = d: {5518 const array_decl_index = d: {
5436 // Add mod.test_functions to an array decl then make the test_functions5519 // Add mod.test_functions to an array decl then make the test_functions
5437 // decl reference it as a slice.5520 // decl reference it as a slice.
5438 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);5521 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
...@@ -5440,50 +5523,52 @@ pub fn populateTestFunctions(mod: *Module) !void {...@@ -5440,50 +5523,52 @@ pub fn populateTestFunctions(mod: *Module) !void {
5440 const arena = new_decl_arena.allocator();5523 const arena = new_decl_arena.allocator();
54415524
5442 const test_fn_vals = try arena.alloc(Value, mod.test_functions.count());5525 const test_fn_vals = try arena.alloc(Value, mod.test_functions.count());
5443 const array_decl = try mod.createAnonymousDeclFromDecl(decl, decl.src_namespace, null, .{5526 const array_decl_index = try mod.createAnonymousDeclFromDecl(decl, decl.src_namespace, null, .{
5444 .ty = try Type.Tag.array.create(arena, .{5527 .ty = try Type.Tag.array.create(arena, .{
5445 .len = test_fn_vals.len,5528 .len = test_fn_vals.len,
5446 .elem_type = try tmp_test_fn_ty.copy(arena),5529 .elem_type = try tmp_test_fn_ty.copy(arena),
5447 }),5530 }),
5448 .val = try Value.Tag.aggregate.create(arena, test_fn_vals),5531 .val = try Value.Tag.aggregate.create(arena, test_fn_vals),
5449 });5532 });
5533 const array_decl = mod.declPtr(array_decl_index);
54505534
5451 // Add a dependency on each test name and function pointer.5535 // Add a dependency on each test name and function pointer.
5452 try array_decl.dependencies.ensureUnusedCapacity(gpa, test_fn_vals.len * 2);5536 try array_decl.dependencies.ensureUnusedCapacity(gpa, test_fn_vals.len * 2);
54535537
5454 for (mod.test_functions.keys()) |test_decl, i| {5538 for (mod.test_functions.keys()) |test_decl_index, i| {
5539 const test_decl = mod.declPtr(test_decl_index);
5455 const test_name_slice = mem.sliceTo(test_decl.name, 0);5540 const test_name_slice = mem.sliceTo(test_decl.name, 0);
5456 const test_name_decl = n: {5541 const test_name_decl_index = n: {
5457 var name_decl_arena = std.heap.ArenaAllocator.init(gpa);5542 var name_decl_arena = std.heap.ArenaAllocator.init(gpa);
5458 errdefer name_decl_arena.deinit();5543 errdefer name_decl_arena.deinit();
5459 const bytes = try name_decl_arena.allocator().dupe(u8, test_name_slice);5544 const bytes = try name_decl_arena.allocator().dupe(u8, test_name_slice);
5460 const test_name_decl = try mod.createAnonymousDeclFromDecl(array_decl, array_decl.src_namespace, null, .{5545 const test_name_decl_index = try mod.createAnonymousDeclFromDecl(array_decl, array_decl.src_namespace, null, .{
5461 .ty = try Type.Tag.array_u8.create(name_decl_arena.allocator(), bytes.len),5546 .ty = try Type.Tag.array_u8.create(name_decl_arena.allocator(), bytes.len),
5462 .val = try Value.Tag.bytes.create(name_decl_arena.allocator(), bytes),5547 .val = try Value.Tag.bytes.create(name_decl_arena.allocator(), bytes),
5463 });5548 });
5464 try test_name_decl.finalizeNewArena(&name_decl_arena);5549 try mod.declPtr(test_name_decl_index).finalizeNewArena(&name_decl_arena);
5465 break :n test_name_decl;5550 break :n test_name_decl_index;
5466 };5551 };
5467 array_decl.dependencies.putAssumeCapacityNoClobber(test_decl, {});5552 array_decl.dependencies.putAssumeCapacityNoClobber(test_decl_index, {});
5468 array_decl.dependencies.putAssumeCapacityNoClobber(test_name_decl, {});5553 array_decl.dependencies.putAssumeCapacityNoClobber(test_name_decl_index, {});
5469 try mod.linkerUpdateDecl(test_name_decl);5554 try mod.linkerUpdateDecl(test_name_decl_index);
54705555
5471 const field_vals = try arena.create([3]Value);5556 const field_vals = try arena.create([3]Value);
5472 field_vals.* = .{5557 field_vals.* = .{
5473 try Value.Tag.slice.create(arena, .{5558 try Value.Tag.slice.create(arena, .{
5474 .ptr = try Value.Tag.decl_ref.create(arena, test_name_decl),5559 .ptr = try Value.Tag.decl_ref.create(arena, test_name_decl_index),
5475 .len = try Value.Tag.int_u64.create(arena, test_name_slice.len),5560 .len = try Value.Tag.int_u64.create(arena, test_name_slice.len),
5476 }), // name5561 }), // name
5477 try Value.Tag.decl_ref.create(arena, test_decl), // func5562 try Value.Tag.decl_ref.create(arena, test_decl_index), // func
5478 Value.initTag(.null_value), // async_frame_size5563 Value.initTag(.null_value), // async_frame_size
5479 };5564 };
5480 test_fn_vals[i] = try Value.Tag.aggregate.create(arena, field_vals);5565 test_fn_vals[i] = try Value.Tag.aggregate.create(arena, field_vals);
5481 }5566 }
54825567
5483 try array_decl.finalizeNewArena(&new_decl_arena);5568 try array_decl.finalizeNewArena(&new_decl_arena);
5484 break :d array_decl;5569 break :d array_decl_index;
5485 };5570 };
5486 try mod.linkerUpdateDecl(array_decl);5571 try mod.linkerUpdateDecl(array_decl_index);
54875572
5488 {5573 {
5489 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);5574 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
...@@ -5493,7 +5578,7 @@ pub fn populateTestFunctions(mod: *Module) !void {...@@ -5493,7 +5578,7 @@ pub fn populateTestFunctions(mod: *Module) !void {
5493 // This copy accesses the old Decl Type/Value so it must be done before `clearValues`.5578 // This copy accesses the old Decl Type/Value so it must be done before `clearValues`.
5494 const new_ty = try Type.Tag.const_slice.create(arena, try tmp_test_fn_ty.copy(arena));5579 const new_ty = try Type.Tag.const_slice.create(arena, try tmp_test_fn_ty.copy(arena));
5495 const new_val = try Value.Tag.slice.create(arena, .{5580 const new_val = try Value.Tag.slice.create(arena, .{
5496 .ptr = try Value.Tag.decl_ref.create(arena, array_decl),5581 .ptr = try Value.Tag.decl_ref.create(arena, array_decl_index),
5497 .len = try Value.Tag.int_u64.create(arena, mod.test_functions.count()),5582 .len = try Value.Tag.int_u64.create(arena, mod.test_functions.count()),
5498 });5583 });
54995584
...@@ -5506,15 +5591,17 @@ pub fn populateTestFunctions(mod: *Module) !void {...@@ -5506,15 +5591,17 @@ pub fn populateTestFunctions(mod: *Module) !void {
55065591
5507 try decl.finalizeNewArena(&new_decl_arena);5592 try decl.finalizeNewArena(&new_decl_arena);
5508 }5593 }
5509 try mod.linkerUpdateDecl(decl);5594 try mod.linkerUpdateDecl(decl_index);
5510}5595}
55115596
5512pub fn linkerUpdateDecl(mod: *Module, decl: *Decl) !void {5597pub fn linkerUpdateDecl(mod: *Module, decl_index: Decl.Index) !void {
5513 const comp = mod.comp;5598 const comp = mod.comp;
55145599
5515 if (comp.bin_file.options.emit == null) return;5600 if (comp.bin_file.options.emit == null) return;
55165601
5517 comp.bin_file.updateDecl(mod, decl) catch |err| switch (err) {5602 const decl = mod.declPtr(decl_index);
5603
5604 comp.bin_file.updateDecl(mod, decl_index) catch |err| switch (err) {
5518 error.OutOfMemory => return error.OutOfMemory,5605 error.OutOfMemory => return error.OutOfMemory,
5519 error.AnalysisFail => {5606 error.AnalysisFail => {
5520 decl.analysis = .codegen_failure;5607 decl.analysis = .codegen_failure;
...@@ -5523,7 +5610,7 @@ pub fn linkerUpdateDecl(mod: *Module, decl: *Decl) !void {...@@ -5523,7 +5610,7 @@ pub fn linkerUpdateDecl(mod: *Module, decl: *Decl) !void {
5523 else => {5610 else => {
5524 const gpa = mod.gpa;5611 const gpa = mod.gpa;
5525 try mod.failed_decls.ensureUnusedCapacity(gpa, 1);5612 try mod.failed_decls.ensureUnusedCapacity(gpa, 1);
5526 mod.failed_decls.putAssumeCapacityNoClobber(decl, try ErrorMsg.create(5613 mod.failed_decls.putAssumeCapacityNoClobber(decl_index, try ErrorMsg.create(
5527 gpa,5614 gpa,
5528 decl.srcLoc(),5615 decl.srcLoc(),
5529 "unable to codegen: {s}",5616 "unable to codegen: {s}",
...@@ -5566,3 +5653,64 @@ fn reportRetryableFileError(...@@ -5566,3 +5653,64 @@ fn reportRetryableFileError(
5566 }5653 }
5567 gop.value_ptr.* = err_msg;5654 gop.value_ptr.* = err_msg;
5568}5655}
5656
5657pub fn markReferencedDeclsAlive(mod: *Module, val: Value) void {
5658 switch (val.tag()) {
5659 .decl_ref_mut => return mod.markDeclIndexAlive(val.castTag(.decl_ref_mut).?.data.decl_index),
5660 .extern_fn => return mod.markDeclIndexAlive(val.castTag(.extern_fn).?.data.owner_decl),
5661 .function => return mod.markDeclIndexAlive(val.castTag(.function).?.data.owner_decl),
5662 .variable => return mod.markDeclIndexAlive(val.castTag(.variable).?.data.owner_decl),
5663 .decl_ref => return mod.markDeclIndexAlive(val.cast(Value.Payload.Decl).?.data),
5664
5665 .repeated,
5666 .eu_payload,
5667 .opt_payload,
5668 .empty_array_sentinel,
5669 => return mod.markReferencedDeclsAlive(val.cast(Value.Payload.SubValue).?.data),
5670
5671 .eu_payload_ptr,
5672 .opt_payload_ptr,
5673 => return mod.markReferencedDeclsAlive(val.cast(Value.Payload.PayloadPtr).?.data.container_ptr),
5674
5675 .slice => {
5676 const slice = val.cast(Value.Payload.Slice).?.data;
5677 mod.markReferencedDeclsAlive(slice.ptr);
5678 mod.markReferencedDeclsAlive(slice.len);
5679 },
5680
5681 .elem_ptr => {
5682 const elem_ptr = val.cast(Value.Payload.ElemPtr).?.data;
5683 return mod.markReferencedDeclsAlive(elem_ptr.array_ptr);
5684 },
5685 .field_ptr => {
5686 const field_ptr = val.cast(Value.Payload.FieldPtr).?.data;
5687 return mod.markReferencedDeclsAlive(field_ptr.container_ptr);
5688 },
5689 .aggregate => {
5690 for (val.castTag(.aggregate).?.data) |field_val| {
5691 mod.markReferencedDeclsAlive(field_val);
5692 }
5693 },
5694 .@"union" => {
5695 const data = val.cast(Value.Payload.Union).?.data;
5696 mod.markReferencedDeclsAlive(data.tag);
5697 mod.markReferencedDeclsAlive(data.val);
5698 },
5699
5700 else => {},
5701 }
5702}
5703
5704pub fn markDeclAlive(mod: *Module, decl: *Decl) void {
5705 if (decl.alive) return;
5706 decl.alive = true;
5707
5708 // This is the first time we are marking this Decl alive. We must
5709 // therefore recurse into its value and mark any Decl it references
5710 // as also alive, so that any Decl referenced does not get garbage collected.
5711 mod.markReferencedDeclsAlive(decl.val);
5712}
5713
5714fn markDeclIndexAlive(mod: *Module, decl_index: Decl.Index) void {
5715 return mod.markDeclAlive(mod.declPtr(decl_index));
5716}
src/RangeSet.zig+16-16
...@@ -1,12 +1,14 @@...@@ -1,12 +1,14 @@
1const std = @import("std");1const std = @import("std");
2const Order = std.math.Order;2const Order = std.math.Order;
3const Type = @import("type.zig").Type;3
4const Value = @import("value.zig").Value;
5const RangeSet = @This();4const RangeSet = @This();
5const Module = @import("Module.zig");
6const SwitchProngSrc = @import("Module.zig").SwitchProngSrc;6const SwitchProngSrc = @import("Module.zig").SwitchProngSrc;
7const Type = @import("type.zig").Type;
8const Value = @import("value.zig").Value;
79
8ranges: std.ArrayList(Range),10ranges: std.ArrayList(Range),
9target: std.Target,11module: *Module,
1012
11pub const Range = struct {13pub const Range = struct {
12 first: Value,14 first: Value,
...@@ -14,10 +16,10 @@ pub const Range = struct {...@@ -14,10 +16,10 @@ pub const Range = struct {
14 src: SwitchProngSrc,16 src: SwitchProngSrc,
15};17};
1618
17pub fn init(allocator: std.mem.Allocator, target: std.Target) RangeSet {19pub fn init(allocator: std.mem.Allocator, module: *Module) RangeSet {
18 return .{20 return .{
19 .ranges = std.ArrayList(Range).init(allocator),21 .ranges = std.ArrayList(Range).init(allocator),
20 .target = target,22 .module = module,
21 };23 };
22}24}
2325
...@@ -32,11 +34,9 @@ pub fn add(...@@ -32,11 +34,9 @@ pub fn add(
32 ty: Type,34 ty: Type,
33 src: SwitchProngSrc,35 src: SwitchProngSrc,
34) !?SwitchProngSrc {36) !?SwitchProngSrc {
35 const target = self.target;
36
37 for (self.ranges.items) |range| {37 for (self.ranges.items) |range| {
38 if (last.compare(.gte, range.first, ty, target) and38 if (last.compare(.gte, range.first, ty, self.module) and
39 first.compare(.lte, range.last, ty, target))39 first.compare(.lte, range.last, ty, self.module))
40 {40 {
41 return range.src; // They overlap.41 return range.src; // They overlap.
42 }42 }
...@@ -49,26 +49,24 @@ pub fn add(...@@ -49,26 +49,24 @@ pub fn add(
49 return null;49 return null;
50}50}
5151
52const LessThanContext = struct { ty: Type, target: std.Target };52const LessThanContext = struct { ty: Type, module: *Module };
5353
54/// Assumes a and b do not overlap54/// Assumes a and b do not overlap
55fn lessThan(ctx: LessThanContext, a: Range, b: Range) bool {55fn lessThan(ctx: LessThanContext, a: Range, b: Range) bool {
56 return a.first.compare(.lt, b.first, ctx.ty, ctx.target);56 return a.first.compare(.lt, b.first, ctx.ty, ctx.module);
57}57}
5858
59pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {59pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {
60 if (self.ranges.items.len == 0)60 if (self.ranges.items.len == 0)
61 return false;61 return false;
6262
63 const target = self.target;
64
65 std.sort.sort(Range, self.ranges.items, LessThanContext{63 std.sort.sort(Range, self.ranges.items, LessThanContext{
66 .ty = ty,64 .ty = ty,
67 .target = target,65 .module = self.module,
68 }, lessThan);66 }, lessThan);
6967
70 if (!self.ranges.items[0].first.eql(first, ty, target) or68 if (!self.ranges.items[0].first.eql(first, ty, self.module) or
71 !self.ranges.items[self.ranges.items.len - 1].last.eql(last, ty, target))69 !self.ranges.items[self.ranges.items.len - 1].last.eql(last, ty, self.module))
72 {70 {
73 return false;71 return false;
74 }72 }
...@@ -78,6 +76,8 @@ pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {...@@ -78,6 +76,8 @@ pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {
78 var counter = try std.math.big.int.Managed.init(self.ranges.allocator);76 var counter = try std.math.big.int.Managed.init(self.ranges.allocator);
79 defer counter.deinit();77 defer counter.deinit();
8078
79 const target = self.module.getTarget();
80
81 // look for gaps81 // look for gaps
82 for (self.ranges.items[1..]) |cur, i| {82 for (self.ranges.items[1..]) |cur, i| {
83 // i starts counting from the second item.83 // i starts counting from the second item.
src/Sema.zig+780-784
...@@ -24,6 +24,7 @@ inst_map: InstMap = .{},...@@ -24,6 +24,7 @@ inst_map: InstMap = .{},
24/// and `src_decl` of `Block` is the `Decl` of the callee.24/// and `src_decl` of `Block` is the `Decl` of the callee.
25/// This `Decl` owns the arena memory of this `Sema`.25/// This `Decl` owns the arena memory of this `Sema`.
26owner_decl: *Decl,26owner_decl: *Decl,
27owner_decl_index: Decl.Index,
27/// For an inline or comptime function call, this will be the root parent function28/// For an inline or comptime function call, this will be the root parent function
28/// which contains the callsite. Corresponds to `owner_decl`.29/// which contains the callsite. Corresponds to `owner_decl`.
29owner_func: ?*Module.Fn,30owner_func: ?*Module.Fn,
...@@ -47,7 +48,7 @@ comptime_break_inst: Zir.Inst.Index = undefined,...@@ -47,7 +48,7 @@ comptime_break_inst: Zir.Inst.Index = undefined,
47/// access to the source location set by the previous instruction which did48/// access to the source location set by the previous instruction which did
48/// contain a mapped source location.49/// contain a mapped source location.
49src: LazySrcLoc = .{ .token_offset = 0 },50src: LazySrcLoc = .{ .token_offset = 0 },
50decl_val_table: std.AutoHashMapUnmanaged(*Decl, Air.Inst.Ref) = .{},51decl_val_table: std.AutoHashMapUnmanaged(Decl.Index, Air.Inst.Ref) = .{},
51/// When doing a generic function instantiation, this array collects a52/// When doing a generic function instantiation, this array collects a
52/// `Value` object for each parameter that is comptime known and thus elided53/// `Value` object for each parameter that is comptime known and thus elided
53/// from the generated function. This memory is allocated by a parent `Sema` and54/// from the generated function. This memory is allocated by a parent `Sema` and
...@@ -111,10 +112,6 @@ pub const Block = struct {...@@ -111,10 +112,6 @@ pub const Block = struct {
111 parent: ?*Block,112 parent: ?*Block,
112 /// Shared among all child blocks.113 /// Shared among all child blocks.
113 sema: *Sema,114 sema: *Sema,
114 /// This Decl is the Decl according to the Zig source code corresponding to this Block.
115 /// This can vary during inline or comptime function calls. See `Sema.owner_decl`
116 /// for the one that will be the same for all Block instances.
117 src_decl: *Decl,
118 /// The namespace to use for lookups from this source block115 /// The namespace to use for lookups from this source block
119 /// When analyzing fields, this is different from src_decl.src_namepsace.116 /// When analyzing fields, this is different from src_decl.src_namepsace.
120 namespace: *Namespace,117 namespace: *Namespace,
...@@ -130,6 +127,10 @@ pub const Block = struct {...@@ -130,6 +127,10 @@ pub const Block = struct {
130 /// If runtime_index is not 0 then one of these is guaranteed to be non null.127 /// If runtime_index is not 0 then one of these is guaranteed to be non null.
131 runtime_cond: ?LazySrcLoc = null,128 runtime_cond: ?LazySrcLoc = null,
132 runtime_loop: ?LazySrcLoc = null,129 runtime_loop: ?LazySrcLoc = null,
130 /// This Decl is the Decl according to the Zig source code corresponding to this Block.
131 /// This can vary during inline or comptime function calls. See `Sema.owner_decl`
132 /// for the one that will be the same for all Block instances.
133 src_decl: Decl.Index,
133 /// Non zero if a non-inline loop or a runtime conditional have been encountered.134 /// Non zero if a non-inline loop or a runtime conditional have been encountered.
134 /// Stores to to comptime variables are only allowed when var.runtime_index <= runtime_index.135 /// Stores to to comptime variables are only allowed when var.runtime_index <= runtime_index.
135 runtime_index: u32 = 0,136 runtime_index: u32 = 0,
...@@ -512,20 +513,21 @@ pub const Block = struct {...@@ -512,20 +513,21 @@ pub const Block = struct {
512 }513 }
513514
514 /// `alignment` value of 0 means to use ABI alignment.515 /// `alignment` value of 0 means to use ABI alignment.
515 pub fn finish(wad: *WipAnonDecl, ty: Type, val: Value, alignment: u32) !*Decl {516 pub fn finish(wad: *WipAnonDecl, ty: Type, val: Value, alignment: u32) !Decl.Index {
516 const sema = wad.block.sema;517 const sema = wad.block.sema;
517 // Do this ahead of time because `createAnonymousDecl` depends on calling518 // Do this ahead of time because `createAnonymousDecl` depends on calling
518 // `type.hasRuntimeBits()`.519 // `type.hasRuntimeBits()`.
519 _ = try sema.typeHasRuntimeBits(wad.block, wad.src, ty);520 _ = try sema.typeHasRuntimeBits(wad.block, wad.src, ty);
520 const new_decl = try sema.mod.createAnonymousDecl(wad.block, .{521 const new_decl_index = try sema.mod.createAnonymousDecl(wad.block, .{
521 .ty = ty,522 .ty = ty,
522 .val = val,523 .val = val,
523 });524 });
525 const new_decl = sema.mod.declPtr(new_decl_index);
524 new_decl.@"align" = alignment;526 new_decl.@"align" = alignment;
525 errdefer sema.mod.abortAnonDecl(new_decl);527 errdefer sema.mod.abortAnonDecl(new_decl_index);
526 try new_decl.finalizeNewArena(&wad.new_decl_arena);528 try new_decl.finalizeNewArena(&wad.new_decl_arena);
527 wad.finished = true;529 wad.finished = true;
528 return new_decl;530 return new_decl_index;
529 }531 }
530 };532 };
531};533};
...@@ -676,7 +678,7 @@ fn analyzeBodyInner(...@@ -676,7 +678,7 @@ fn analyzeBodyInner(
676 crash_info.setBodyIndex(i);678 crash_info.setBodyIndex(i);
677 const inst = body[i];679 const inst = body[i];
678 std.log.scoped(.sema_zir).debug("sema ZIR {s} %{d}", .{680 std.log.scoped(.sema_zir).debug("sema ZIR {s} %{d}", .{
679 block.src_decl.src_namespace.file_scope.sub_file_path, inst,681 sema.mod.declPtr(block.src_decl).src_namespace.file_scope.sub_file_path, inst,
680 });682 });
681 const air_inst: Air.Inst.Ref = switch (tags[inst]) {683 const air_inst: Air.Inst.Ref = switch (tags[inst]) {
682 // zig fmt: off684 // zig fmt: off
...@@ -1383,8 +1385,7 @@ pub fn resolveConstString(...@@ -1383,8 +1385,7 @@ pub fn resolveConstString(
1383 const wanted_type = Type.initTag(.const_slice_u8);1385 const wanted_type = Type.initTag(.const_slice_u8);
1384 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);1386 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
1385 const val = try sema.resolveConstValue(block, src, coerced_inst);1387 const val = try sema.resolveConstValue(block, src, coerced_inst);
1386 const target = sema.mod.getTarget();1388 return val.toAllocatedBytes(wanted_type, sema.arena, sema.mod);
1387 return val.toAllocatedBytes(wanted_type, sema.arena, target);
1388}1389}
13891390
1390pub fn resolveType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !Type {1391pub fn resolveType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !Type {
...@@ -1538,28 +1539,24 @@ fn failWithDivideByZero(sema: *Sema, block: *Block, src: LazySrcLoc) CompileErro...@@ -1538,28 +1539,24 @@ fn failWithDivideByZero(sema: *Sema, block: *Block, src: LazySrcLoc) CompileErro
1538}1539}
15391540
1540fn failWithModRemNegative(sema: *Sema, block: *Block, src: LazySrcLoc, lhs_ty: Type, rhs_ty: Type) CompileError {1541fn failWithModRemNegative(sema: *Sema, block: *Block, src: LazySrcLoc, lhs_ty: Type, rhs_ty: Type) CompileError {
1541 const target = sema.mod.getTarget();
1542 return sema.fail(block, src, "remainder division with '{}' and '{}': signed integers and floats must use @rem or @mod", .{1542 return sema.fail(block, src, "remainder division with '{}' and '{}': signed integers and floats must use @rem or @mod", .{
1543 lhs_ty.fmt(target), rhs_ty.fmt(target),1543 lhs_ty.fmt(sema.mod), rhs_ty.fmt(sema.mod),
1544 });1544 });
1545}1545}
15461546
1547fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, optional_ty: Type) CompileError {1547fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, optional_ty: Type) CompileError {
1548 const target = sema.mod.getTarget();1548 return sema.fail(block, src, "expected optional type, found {}", .{optional_ty.fmt(sema.mod)});
1549 return sema.fail(block, src, "expected optional type, found {}", .{optional_ty.fmt(target)});
1550}1549}
15511550
1552fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {1551fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
1553 const target = sema.mod.getTarget();
1554 return sema.fail(block, src, "type '{}' does not support array initialization syntax", .{1552 return sema.fail(block, src, "type '{}' does not support array initialization syntax", .{
1555 ty.fmt(target),1553 ty.fmt(sema.mod),
1556 });1554 });
1557}1555}
15581556
1559fn failWithStructInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {1557fn failWithStructInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
1560 const target = sema.mod.getTarget();
1561 return sema.fail(block, src, "type '{}' does not support struct initialization syntax", .{1558 return sema.fail(block, src, "type '{}' does not support struct initialization syntax", .{
1562 ty.fmt(target),1559 ty.fmt(sema.mod),
1563 });1560 });
1564}1561}
15651562
...@@ -1570,9 +1567,8 @@ fn failWithErrorSetCodeMissing(...@@ -1570,9 +1567,8 @@ fn failWithErrorSetCodeMissing(
1570 dest_err_set_ty: Type,1567 dest_err_set_ty: Type,
1571 src_err_set_ty: Type,1568 src_err_set_ty: Type,
1572) CompileError {1569) CompileError {
1573 const target = sema.mod.getTarget();
1574 return sema.fail(block, src, "expected type '{}', found type '{}'", .{1570 return sema.fail(block, src, "expected type '{}', found type '{}'", .{
1575 dest_err_set_ty.fmt(target), src_err_set_ty.fmt(target),1571 dest_err_set_ty.fmt(sema.mod), src_err_set_ty.fmt(sema.mod),
1576 });1572 });
1577}1573}
15781574
...@@ -1586,7 +1582,9 @@ fn errNote(...@@ -1586,7 +1582,9 @@ fn errNote(
1586 comptime format: []const u8,1582 comptime format: []const u8,
1587 args: anytype,1583 args: anytype,
1588) error{OutOfMemory}!void {1584) error{OutOfMemory}!void {
1589 return sema.mod.errNoteNonLazy(src.toSrcLoc(block.src_decl), parent, format, args);1585 const mod = sema.mod;
1586 const src_decl = mod.declPtr(block.src_decl);
1587 return mod.errNoteNonLazy(src.toSrcLoc(src_decl), parent, format, args);
1590}1588}
15911589
1592fn addFieldErrNote(1590fn addFieldErrNote(
...@@ -1598,10 +1596,12 @@ fn addFieldErrNote(...@@ -1598,10 +1596,12 @@ fn addFieldErrNote(
1598 comptime format: []const u8,1596 comptime format: []const u8,
1599 args: anytype,1597 args: anytype,
1600) !void {1598) !void {
1601 const decl = container_ty.getOwnerDecl();1599 const mod = sema.mod;
1600 const decl_index = container_ty.getOwnerDecl();
1601 const decl = mod.declPtr(decl_index);
1602 const tree = try sema.getAstTree(block);1602 const tree = try sema.getAstTree(block);
1603 const field_src = enumFieldSrcLoc(decl, tree.*, container_ty.getNodeOffset(), field_index);1603 const field_src = enumFieldSrcLoc(decl, tree.*, container_ty.getNodeOffset(), field_index);
1604 try sema.mod.errNoteNonLazy(field_src.toSrcLoc(decl), parent, format, args);1604 try mod.errNoteNonLazy(field_src.toSrcLoc(decl), parent, format, args);
1605}1605}
16061606
1607fn errMsg(1607fn errMsg(
...@@ -1611,7 +1611,9 @@ fn errMsg(...@@ -1611,7 +1611,9 @@ fn errMsg(
1611 comptime format: []const u8,1611 comptime format: []const u8,
1612 args: anytype,1612 args: anytype,
1613) error{OutOfMemory}!*Module.ErrorMsg {1613) error{OutOfMemory}!*Module.ErrorMsg {
1614 return Module.ErrorMsg.create(sema.gpa, src.toSrcLoc(block.src_decl), format, args);1614 const mod = sema.mod;
1615 const src_decl = mod.declPtr(block.src_decl);
1616 return Module.ErrorMsg.create(sema.gpa, src.toSrcLoc(src_decl), format, args);
1615}1617}
16161618
1617pub fn fail(1619pub fn fail(
...@@ -1654,7 +1656,7 @@ fn failWithOwnedErrorMsg(sema: *Sema, block: *Block, err_msg: *Module.ErrorMsg)...@@ -1654,7 +1656,7 @@ fn failWithOwnedErrorMsg(sema: *Sema, block: *Block, err_msg: *Module.ErrorMsg)
1654 sema.owner_decl.analysis = .sema_failure;1656 sema.owner_decl.analysis = .sema_failure;
1655 sema.owner_decl.generation = mod.generation;1657 sema.owner_decl.generation = mod.generation;
1656 }1658 }
1657 const gop = mod.failed_decls.getOrPutAssumeCapacity(sema.owner_decl);1659 const gop = mod.failed_decls.getOrPutAssumeCapacity(sema.owner_decl_index);
1658 if (gop.found_existing) {1660 if (gop.found_existing) {
1659 // If there are multiple errors for the same Decl, prefer the first one added.1661 // If there are multiple errors for the same Decl, prefer the first one added.
1660 err_msg.destroy(mod.gpa);1662 err_msg.destroy(mod.gpa);
...@@ -1756,7 +1758,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -1756,7 +1758,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
1756 try inferred_alloc.stored_inst_list.append(sema.arena, operand);1758 try inferred_alloc.stored_inst_list.append(sema.arena, operand);
17571759
1758 try sema.requireRuntimeBlock(block, src);1760 try sema.requireRuntimeBlock(block, src);
1759 const ptr_ty = try Type.ptr(sema.arena, target, .{1761 const ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
1760 .pointee_type = pointee_ty,1762 .pointee_type = pointee_ty,
1761 .@"align" = inferred_alloc.alignment,1763 .@"align" = inferred_alloc.alignment,
1762 .@"addrspace" = addr_space,1764 .@"addrspace" = addr_space,
...@@ -1770,7 +1772,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -1770,7 +1772,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
1770 // The alloc will turn into a Decl.1772 // The alloc will turn into a Decl.
1771 var anon_decl = try block.startAnonDecl(src);1773 var anon_decl = try block.startAnonDecl(src);
1772 defer anon_decl.deinit();1774 defer anon_decl.deinit();
1773 iac.data.decl = try anon_decl.finish(1775 iac.data.decl_index = try anon_decl.finish(
1774 try pointee_ty.copy(anon_decl.arena()),1776 try pointee_ty.copy(anon_decl.arena()),
1775 Value.undef,1777 Value.undef,
1776 iac.data.alignment,1778 iac.data.alignment,
...@@ -1778,7 +1780,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -1778,7 +1780,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
1778 if (iac.data.alignment != 0) {1780 if (iac.data.alignment != 0) {
1779 try sema.resolveTypeLayout(block, src, pointee_ty);1781 try sema.resolveTypeLayout(block, src, pointee_ty);
1780 }1782 }
1781 const ptr_ty = try Type.ptr(sema.arena, target, .{1783 const ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
1782 .pointee_type = pointee_ty,1784 .pointee_type = pointee_ty,
1783 .@"align" = iac.data.alignment,1785 .@"align" = iac.data.alignment,
1784 .@"addrspace" = addr_space,1786 .@"addrspace" = addr_space,
...@@ -1786,7 +1788,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -1786,7 +1788,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
1786 return sema.addConstant(1788 return sema.addConstant(
1787 ptr_ty,1789 ptr_ty,
1788 try Value.Tag.decl_ref_mut.create(sema.arena, .{1790 try Value.Tag.decl_ref_mut.create(sema.arena, .{
1789 .decl = iac.data.decl,1791 .decl_index = iac.data.decl_index,
1790 .runtime_index = block.runtime_index,1792 .runtime_index = block.runtime_index,
1791 }),1793 }),
1792 );1794 );
...@@ -1827,7 +1829,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -1827,7 +1829,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
1827 }1829 }
1828 }1830 }
18291831
1830 const ptr_ty = try Type.ptr(sema.arena, target, .{1832 const ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
1831 .pointee_type = pointee_ty,1833 .pointee_type = pointee_ty,
1832 .@"addrspace" = addr_space,1834 .@"addrspace" = addr_space,
1833 });1835 });
...@@ -1848,7 +1850,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -1848,7 +1850,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
1848 }1850 }
1849 const ty_op = air_datas[trash_inst].ty_op;1851 const ty_op = air_datas[trash_inst].ty_op;
1850 const operand_ty = sema.typeOf(ty_op.operand);1852 const operand_ty = sema.typeOf(ty_op.operand);
1851 const ptr_operand_ty = try Type.ptr(sema.arena, target, .{1853 const ptr_operand_ty = try Type.ptr(sema.arena, sema.mod, .{
1852 .pointee_type = operand_ty,1854 .pointee_type = operand_ty,
1853 .@"addrspace" = addr_space,1855 .@"addrspace" = addr_space,
1854 });1856 });
...@@ -1924,18 +1926,19 @@ fn zirStructDecl(...@@ -1924,18 +1926,19 @@ fn zirStructDecl(
1924 errdefer new_decl_arena.deinit();1926 errdefer new_decl_arena.deinit();
1925 const new_decl_arena_allocator = new_decl_arena.allocator();1927 const new_decl_arena_allocator = new_decl_arena.allocator();
19261928
1929 const mod = sema.mod;
1927 const struct_obj = try new_decl_arena_allocator.create(Module.Struct);1930 const struct_obj = try new_decl_arena_allocator.create(Module.Struct);
1928 const struct_ty = try Type.Tag.@"struct".create(new_decl_arena_allocator, struct_obj);1931 const struct_ty = try Type.Tag.@"struct".create(new_decl_arena_allocator, struct_obj);
1929 const struct_val = try Value.Tag.ty.create(new_decl_arena_allocator, struct_ty);1932 const struct_val = try Value.Tag.ty.create(new_decl_arena_allocator, struct_ty);
1930 const type_name = try sema.createTypeName(block, small.name_strategy, "struct");1933 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
1931 const new_decl = try sema.mod.createAnonymousDeclNamed(block, .{
1932 .ty = Type.type,1934 .ty = Type.type,
1933 .val = struct_val,1935 .val = struct_val,
1934 }, type_name);1936 }, small.name_strategy, "struct");
1937 const new_decl = mod.declPtr(new_decl_index);
1935 new_decl.owns_tv = true;1938 new_decl.owns_tv = true;
1936 errdefer sema.mod.abortAnonDecl(new_decl);1939 errdefer mod.abortAnonDecl(new_decl_index);
1937 struct_obj.* = .{1940 struct_obj.* = .{
1938 .owner_decl = new_decl,1941 .owner_decl = new_decl_index,
1939 .fields = .{},1942 .fields = .{},
1940 .node_offset = src.node_offset,1943 .node_offset = src.node_offset,
1941 .zir_index = inst,1944 .zir_index = inst,
...@@ -1953,15 +1956,23 @@ fn zirStructDecl(...@@ -1953,15 +1956,23 @@ fn zirStructDecl(
1953 });1956 });
1954 try sema.analyzeStructDecl(new_decl, inst, struct_obj);1957 try sema.analyzeStructDecl(new_decl, inst, struct_obj);
1955 try new_decl.finalizeNewArena(&new_decl_arena);1958 try new_decl.finalizeNewArena(&new_decl_arena);
1956 return sema.analyzeDeclVal(block, src, new_decl);1959 return sema.analyzeDeclVal(block, src, new_decl_index);
1957}1960}
19581961
1959fn createTypeName(1962fn createAnonymousDeclTypeNamed(
1960 sema: *Sema,1963 sema: *Sema,
1961 block: *Block,1964 block: *Block,
1965 typed_value: TypedValue,
1962 name_strategy: Zir.Inst.NameStrategy,1966 name_strategy: Zir.Inst.NameStrategy,
1963 anon_prefix: []const u8,1967 anon_prefix: []const u8,
1964) ![:0]u8 {1968) !Decl.Index {
1969 const mod = sema.mod;
1970 const namespace = block.namespace;
1971 const src_scope = block.wip_capture_scope;
1972 const src_decl = mod.declPtr(block.src_decl);
1973 const new_decl_index = try mod.allocateNewDecl(namespace, src_decl.src_node, src_scope);
1974 errdefer mod.destroyDecl(new_decl_index);
1975
1965 switch (name_strategy) {1976 switch (name_strategy) {
1966 .anon => {1977 .anon => {
1967 // It would be neat to have "struct:line:column" but this name has1978 // It would be neat to have "struct:line:column" but this name has
...@@ -1970,20 +1981,24 @@ fn createTypeName(...@@ -1970,20 +1981,24 @@ fn createTypeName(
1970 // semantically analyzed.1981 // semantically analyzed.
1971 // This name is also used as the key in the parent namespace so it cannot be1982 // This name is also used as the key in the parent namespace so it cannot be
1972 // renamed.1983 // renamed.
1973 const name_index = sema.mod.getNextAnonNameIndex();1984 const name = try std.fmt.allocPrintZ(sema.gpa, "{s}__{s}_{d}", .{
1974 return std.fmt.allocPrintZ(sema.gpa, "{s}__{s}_{d}", .{1985 src_decl.name, anon_prefix, @enumToInt(new_decl_index),
1975 block.src_decl.name, anon_prefix, name_index,
1976 });1986 });
1987 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);
1988 return new_decl_index;
1989 },
1990 .parent => {
1991 const name = try sema.gpa.dupeZ(u8, mem.sliceTo(sema.mod.declPtr(block.src_decl).name, 0));
1992 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);
1993 return new_decl_index;
1977 },1994 },
1978 .parent => return sema.gpa.dupeZ(u8, mem.sliceTo(block.src_decl.name, 0)),
1979 .func => {1995 .func => {
1980 const target = sema.mod.getTarget();
1981 const fn_info = sema.code.getFnInfo(sema.func.?.zir_body_inst);1996 const fn_info = sema.code.getFnInfo(sema.func.?.zir_body_inst);
1982 const zir_tags = sema.code.instructions.items(.tag);1997 const zir_tags = sema.code.instructions.items(.tag);
19831998
1984 var buf = std.ArrayList(u8).init(sema.gpa);1999 var buf = std.ArrayList(u8).init(sema.gpa);
1985 defer buf.deinit();2000 defer buf.deinit();
1986 try buf.appendSlice(mem.sliceTo(block.src_decl.name, 0));2001 try buf.appendSlice(mem.sliceTo(sema.mod.declPtr(block.src_decl).name, 0));
1987 try buf.appendSlice("(");2002 try buf.appendSlice("(");
19882003
1989 var arg_i: usize = 0;2004 var arg_i: usize = 0;
...@@ -1995,7 +2010,7 @@ fn createTypeName(...@@ -1995,7 +2010,7 @@ fn createTypeName(
1995 const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg) catch unreachable;2010 const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg) catch unreachable;
19962011
1997 if (arg_i != 0) try buf.appendSlice(",");2012 if (arg_i != 0) try buf.appendSlice(",");
1998 try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg), target)});2013 try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg), sema.mod)});
19992014
2000 arg_i += 1;2015 arg_i += 1;
2001 continue;2016 continue;
...@@ -2004,7 +2019,9 @@ fn createTypeName(...@@ -2004,7 +2019,9 @@ fn createTypeName(
2004 };2019 };
20052020
2006 try buf.appendSlice(")");2021 try buf.appendSlice(")");
2007 return buf.toOwnedSliceSentinel(0);2022 const name = try buf.toOwnedSliceSentinel(0);
2023 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);
2024 return new_decl_index;
2008 },2025 },
2009 }2026 }
2010}2027}
...@@ -2064,16 +2081,16 @@ fn zirEnumDecl(...@@ -2064,16 +2081,16 @@ fn zirEnumDecl(
2064 };2081 };
2065 const enum_ty = Type.initPayload(&enum_ty_payload.base);2082 const enum_ty = Type.initPayload(&enum_ty_payload.base);
2066 const enum_val = try Value.Tag.ty.create(new_decl_arena_allocator, enum_ty);2083 const enum_val = try Value.Tag.ty.create(new_decl_arena_allocator, enum_ty);
2067 const type_name = try sema.createTypeName(block, small.name_strategy, "enum");2084 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
2068 const new_decl = try mod.createAnonymousDeclNamed(block, .{
2069 .ty = Type.type,2085 .ty = Type.type,
2070 .val = enum_val,2086 .val = enum_val,
2071 }, type_name);2087 }, small.name_strategy, "enum");
2088 const new_decl = mod.declPtr(new_decl_index);
2072 new_decl.owns_tv = true;2089 new_decl.owns_tv = true;
2073 errdefer mod.abortAnonDecl(new_decl);2090 errdefer mod.abortAnonDecl(new_decl_index);
20742091
2075 enum_obj.* = .{2092 enum_obj.* = .{
2076 .owner_decl = new_decl,2093 .owner_decl = new_decl_index,
2077 .tag_ty = Type.@"null",2094 .tag_ty = Type.@"null",
2078 .tag_ty_inferred = true,2095 .tag_ty_inferred = true,
2079 .fields = .{},2096 .fields = .{},
...@@ -2101,7 +2118,7 @@ fn zirEnumDecl(...@@ -2101,7 +2118,7 @@ fn zirEnumDecl(
2101 enum_obj.tag_ty_inferred = false;2118 enum_obj.tag_ty_inferred = false;
2102 }2119 }
2103 try new_decl.finalizeNewArena(&new_decl_arena);2120 try new_decl.finalizeNewArena(&new_decl_arena);
2104 return sema.analyzeDeclVal(block, src, new_decl);2121 return sema.analyzeDeclVal(block, src, new_decl_index);
2105 }2122 }
2106 extra_index += body.len;2123 extra_index += body.len;
21072124
...@@ -2116,8 +2133,13 @@ fn zirEnumDecl(...@@ -2116,8 +2133,13 @@ fn zirEnumDecl(
2116 // should be the enum itself.2133 // should be the enum itself.
21172134
2118 const prev_owner_decl = sema.owner_decl;2135 const prev_owner_decl = sema.owner_decl;
2136 const prev_owner_decl_index = sema.owner_decl_index;
2119 sema.owner_decl = new_decl;2137 sema.owner_decl = new_decl;
2120 defer sema.owner_decl = prev_owner_decl;2138 sema.owner_decl_index = new_decl_index;
2139 defer {
2140 sema.owner_decl = prev_owner_decl;
2141 sema.owner_decl_index = prev_owner_decl_index;
2142 }
21212143
2122 const prev_owner_func = sema.owner_func;2144 const prev_owner_func = sema.owner_func;
2123 sema.owner_func = null;2145 sema.owner_func = null;
...@@ -2133,7 +2155,7 @@ fn zirEnumDecl(...@@ -2133,7 +2155,7 @@ fn zirEnumDecl(
2133 var enum_block: Block = .{2155 var enum_block: Block = .{
2134 .parent = null,2156 .parent = null,
2135 .sema = sema,2157 .sema = sema,
2136 .src_decl = new_decl,2158 .src_decl = new_decl_index,
2137 .namespace = &enum_obj.namespace,2159 .namespace = &enum_obj.namespace,
2138 .wip_capture_scope = wip_captures.scope,2160 .wip_capture_scope = wip_captures.scope,
2139 .instructions = .{},2161 .instructions = .{},
...@@ -2168,7 +2190,7 @@ fn zirEnumDecl(...@@ -2168,7 +2190,7 @@ fn zirEnumDecl(
2168 if (any_values) {2190 if (any_values) {
2169 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{2191 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{
2170 .ty = enum_obj.tag_ty,2192 .ty = enum_obj.tag_ty,
2171 .target = target,2193 .mod = mod,
2172 });2194 });
2173 }2195 }
21742196
...@@ -2196,8 +2218,8 @@ fn zirEnumDecl(...@@ -2196,8 +2218,8 @@ fn zirEnumDecl(
2196 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);2218 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);
2197 if (gop.found_existing) {2219 if (gop.found_existing) {
2198 const tree = try sema.getAstTree(block);2220 const tree = try sema.getAstTree(block);
2199 const field_src = enumFieldSrcLoc(block.src_decl, tree.*, src.node_offset, field_i);2221 const field_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset, field_i);
2200 const other_tag_src = enumFieldSrcLoc(block.src_decl, tree.*, src.node_offset, gop.index);2222 const other_tag_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset, gop.index);
2201 const msg = msg: {2223 const msg = msg: {
2202 const msg = try sema.errMsg(block, field_src, "duplicate enum tag", .{});2224 const msg = try sema.errMsg(block, field_src, "duplicate enum tag", .{});
2203 errdefer msg.destroy(gpa);2225 errdefer msg.destroy(gpa);
...@@ -2218,7 +2240,7 @@ fn zirEnumDecl(...@@ -2218,7 +2240,7 @@ fn zirEnumDecl(
2218 const copied_tag_val = try tag_val.copy(new_decl_arena_allocator);2240 const copied_tag_val = try tag_val.copy(new_decl_arena_allocator);
2219 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{2241 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{
2220 .ty = enum_obj.tag_ty,2242 .ty = enum_obj.tag_ty,
2221 .target = target,2243 .mod = mod,
2222 });2244 });
2223 } else if (any_values) {2245 } else if (any_values) {
2224 const tag_val = if (last_tag_val) |val|2246 const tag_val = if (last_tag_val) |val|
...@@ -2229,13 +2251,13 @@ fn zirEnumDecl(...@@ -2229,13 +2251,13 @@ fn zirEnumDecl(
2229 const copied_tag_val = try tag_val.copy(new_decl_arena_allocator);2251 const copied_tag_val = try tag_val.copy(new_decl_arena_allocator);
2230 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{2252 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{
2231 .ty = enum_obj.tag_ty,2253 .ty = enum_obj.tag_ty,
2232 .target = target,2254 .mod = mod,
2233 });2255 });
2234 }2256 }
2235 }2257 }
22362258
2237 try new_decl.finalizeNewArena(&new_decl_arena);2259 try new_decl.finalizeNewArena(&new_decl_arena);
2238 return sema.analyzeDeclVal(block, src, new_decl);2260 return sema.analyzeDeclVal(block, src, new_decl_index);
2239}2261}
22402262
2241fn zirUnionDecl(2263fn zirUnionDecl(
...@@ -2279,15 +2301,16 @@ fn zirUnionDecl(...@@ -2279,15 +2301,16 @@ fn zirUnionDecl(
2279 };2301 };
2280 const union_ty = Type.initPayload(&union_payload.base);2302 const union_ty = Type.initPayload(&union_payload.base);
2281 const union_val = try Value.Tag.ty.create(new_decl_arena_allocator, union_ty);2303 const union_val = try Value.Tag.ty.create(new_decl_arena_allocator, union_ty);
2282 const type_name = try sema.createTypeName(block, small.name_strategy, "union");2304 const mod = sema.mod;
2283 const new_decl = try sema.mod.createAnonymousDeclNamed(block, .{2305 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
2284 .ty = Type.type,2306 .ty = Type.type,
2285 .val = union_val,2307 .val = union_val,
2286 }, type_name);2308 }, small.name_strategy, "union");
2309 const new_decl = mod.declPtr(new_decl_index);
2287 new_decl.owns_tv = true;2310 new_decl.owns_tv = true;
2288 errdefer sema.mod.abortAnonDecl(new_decl);2311 errdefer mod.abortAnonDecl(new_decl_index);
2289 union_obj.* = .{2312 union_obj.* = .{
2290 .owner_decl = new_decl,2313 .owner_decl = new_decl_index,
2291 .tag_ty = Type.initTag(.@"null"),2314 .tag_ty = Type.initTag(.@"null"),
2292 .fields = .{},2315 .fields = .{},
2293 .node_offset = src.node_offset,2316 .node_offset = src.node_offset,
...@@ -2304,10 +2327,10 @@ fn zirUnionDecl(...@@ -2304,10 +2327,10 @@ fn zirUnionDecl(
2304 &union_obj.namespace, new_decl, new_decl.name,2327 &union_obj.namespace, new_decl, new_decl.name,
2305 });2328 });
23062329
2307 _ = try sema.mod.scanNamespace(&union_obj.namespace, extra_index, decls_len, new_decl);2330 _ = try mod.scanNamespace(&union_obj.namespace, extra_index, decls_len, new_decl);
23082331
2309 try new_decl.finalizeNewArena(&new_decl_arena);2332 try new_decl.finalizeNewArena(&new_decl_arena);
2310 return sema.analyzeDeclVal(block, src, new_decl);2333 return sema.analyzeDeclVal(block, src, new_decl_index);
2311}2334}
23122335
2313fn zirOpaqueDecl(2336fn zirOpaqueDecl(
...@@ -2347,16 +2370,16 @@ fn zirOpaqueDecl(...@@ -2347,16 +2370,16 @@ fn zirOpaqueDecl(
2347 };2370 };
2348 const opaque_ty = Type.initPayload(&opaque_ty_payload.base);2371 const opaque_ty = Type.initPayload(&opaque_ty_payload.base);
2349 const opaque_val = try Value.Tag.ty.create(new_decl_arena_allocator, opaque_ty);2372 const opaque_val = try Value.Tag.ty.create(new_decl_arena_allocator, opaque_ty);
2350 const type_name = try sema.createTypeName(block, small.name_strategy, "opaque");2373 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
2351 const new_decl = try mod.createAnonymousDeclNamed(block, .{
2352 .ty = Type.type,2374 .ty = Type.type,
2353 .val = opaque_val,2375 .val = opaque_val,
2354 }, type_name);2376 }, small.name_strategy, "opaque");
2377 const new_decl = mod.declPtr(new_decl_index);
2355 new_decl.owns_tv = true;2378 new_decl.owns_tv = true;
2356 errdefer mod.abortAnonDecl(new_decl);2379 errdefer mod.abortAnonDecl(new_decl_index);
23572380
2358 opaque_obj.* = .{2381 opaque_obj.* = .{
2359 .owner_decl = new_decl,2382 .owner_decl = new_decl_index,
2360 .node_offset = src.node_offset,2383 .node_offset = src.node_offset,
2361 .namespace = .{2384 .namespace = .{
2362 .parent = block.namespace,2385 .parent = block.namespace,
...@@ -2371,7 +2394,7 @@ fn zirOpaqueDecl(...@@ -2371,7 +2394,7 @@ fn zirOpaqueDecl(
2371 extra_index = try mod.scanNamespace(&opaque_obj.namespace, extra_index, decls_len, new_decl);2394 extra_index = try mod.scanNamespace(&opaque_obj.namespace, extra_index, decls_len, new_decl);
23722395
2373 try new_decl.finalizeNewArena(&new_decl_arena);2396 try new_decl.finalizeNewArena(&new_decl_arena);
2374 return sema.analyzeDeclVal(block, src, new_decl);2397 return sema.analyzeDeclVal(block, src, new_decl_index);
2375}2398}
23762399
2377fn zirErrorSetDecl(2400fn zirErrorSetDecl(
...@@ -2395,13 +2418,14 @@ fn zirErrorSetDecl(...@@ -2395,13 +2418,14 @@ fn zirErrorSetDecl(
2395 const error_set = try new_decl_arena_allocator.create(Module.ErrorSet);2418 const error_set = try new_decl_arena_allocator.create(Module.ErrorSet);
2396 const error_set_ty = try Type.Tag.error_set.create(new_decl_arena_allocator, error_set);2419 const error_set_ty = try Type.Tag.error_set.create(new_decl_arena_allocator, error_set);
2397 const error_set_val = try Value.Tag.ty.create(new_decl_arena_allocator, error_set_ty);2420 const error_set_val = try Value.Tag.ty.create(new_decl_arena_allocator, error_set_ty);
2398 const type_name = try sema.createTypeName(block, name_strategy, "error");2421 const mod = sema.mod;
2399 const new_decl = try sema.mod.createAnonymousDeclNamed(block, .{2422 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
2400 .ty = Type.type,2423 .ty = Type.type,
2401 .val = error_set_val,2424 .val = error_set_val,
2402 }, type_name);2425 }, name_strategy, "error");
2426 const new_decl = mod.declPtr(new_decl_index);
2403 new_decl.owns_tv = true;2427 new_decl.owns_tv = true;
2404 errdefer sema.mod.abortAnonDecl(new_decl);2428 errdefer mod.abortAnonDecl(new_decl_index);
24052429
2406 var names = Module.ErrorSet.NameMap{};2430 var names = Module.ErrorSet.NameMap{};
2407 try names.ensureUnusedCapacity(new_decl_arena_allocator, extra.data.fields_len);2431 try names.ensureUnusedCapacity(new_decl_arena_allocator, extra.data.fields_len);
...@@ -2410,7 +2434,7 @@ fn zirErrorSetDecl(...@@ -2410,7 +2434,7 @@ fn zirErrorSetDecl(
2410 const extra_index_end = extra_index + (extra.data.fields_len * 2);2434 const extra_index_end = extra_index + (extra.data.fields_len * 2);
2411 while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string2435 while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string
2412 const str_index = sema.code.extra[extra_index];2436 const str_index = sema.code.extra[extra_index];
2413 const kv = try sema.mod.getErrorValue(sema.code.nullTerminatedString(str_index));2437 const kv = try mod.getErrorValue(sema.code.nullTerminatedString(str_index));
2414 const result = names.getOrPutAssumeCapacity(kv.key);2438 const result = names.getOrPutAssumeCapacity(kv.key);
2415 assert(!result.found_existing); // verified in AstGen2439 assert(!result.found_existing); // verified in AstGen
2416 }2440 }
...@@ -2419,12 +2443,12 @@ fn zirErrorSetDecl(...@@ -2419,12 +2443,12 @@ fn zirErrorSetDecl(
2419 Module.ErrorSet.sortNames(&names);2443 Module.ErrorSet.sortNames(&names);
24202444
2421 error_set.* = .{2445 error_set.* = .{
2422 .owner_decl = new_decl,2446 .owner_decl = new_decl_index,
2423 .node_offset = inst_data.src_node,2447 .node_offset = inst_data.src_node,
2424 .names = names,2448 .names = names,
2425 };2449 };
2426 try new_decl.finalizeNewArena(&new_decl_arena);2450 try new_decl.finalizeNewArena(&new_decl_arena);
2427 return sema.analyzeDeclVal(block, src, new_decl);2451 return sema.analyzeDeclVal(block, src, new_decl_index);
2428}2452}
24292453
2430fn zirRetPtr(2454fn zirRetPtr(
...@@ -2444,7 +2468,7 @@ fn zirRetPtr(...@@ -2444,7 +2468,7 @@ fn zirRetPtr(
2444 }2468 }
24452469
2446 const target = sema.mod.getTarget();2470 const target = sema.mod.getTarget();
2447 const ptr_type = try Type.ptr(sema.arena, target, .{2471 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
2448 .pointee_type = sema.fn_ret_ty,2472 .pointee_type = sema.fn_ret_ty,
2449 .@"addrspace" = target_util.defaultAddressSpace(target, .local),2473 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
2450 });2474 });
...@@ -2535,14 +2559,13 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -2535,14 +2559,13 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
2535 else2559 else
2536 object_ty;2560 object_ty;
25372561
2538 const target = sema.mod.getTarget();
2539 if (!array_ty.isIndexable()) {2562 if (!array_ty.isIndexable()) {
2540 const msg = msg: {2563 const msg = msg: {
2541 const msg = try sema.errMsg(2564 const msg = try sema.errMsg(
2542 block,2565 block,
2543 src,2566 src,
2544 "type '{}' does not support indexing",2567 "type '{}' does not support indexing",
2545 .{array_ty.fmt(target)},2568 .{array_ty.fmt(sema.mod)},
2546 );2569 );
2547 errdefer msg.destroy(sema.gpa);2570 errdefer msg.destroy(sema.gpa);
2548 try sema.errNote(2571 try sema.errNote(
...@@ -2598,7 +2621,7 @@ fn zirAllocExtended(...@@ -2598,7 +2621,7 @@ fn zirAllocExtended(
2598 return sema.addConstant(2621 return sema.addConstant(
2599 inferred_alloc_ty,2622 inferred_alloc_ty,
2600 try Value.Tag.inferred_alloc_comptime.create(sema.arena, .{2623 try Value.Tag.inferred_alloc_comptime.create(sema.arena, .{
2601 .decl = undefined,2624 .decl_index = undefined,
2602 .alignment = alignment,2625 .alignment = alignment,
2603 }),2626 }),
2604 );2627 );
...@@ -2612,7 +2635,7 @@ fn zirAllocExtended(...@@ -2612,7 +2635,7 @@ fn zirAllocExtended(
2612 const target = sema.mod.getTarget();2635 const target = sema.mod.getTarget();
2613 try sema.requireRuntimeBlock(block, src);2636 try sema.requireRuntimeBlock(block, src);
2614 try sema.resolveTypeLayout(block, src, var_ty);2637 try sema.resolveTypeLayout(block, src, var_ty);
2615 const ptr_type = try Type.ptr(sema.arena, target, .{2638 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
2616 .pointee_type = var_ty,2639 .pointee_type = var_ty,
2617 .@"align" = alignment,2640 .@"align" = alignment,
2618 .@"addrspace" = target_util.defaultAddressSpace(target, .local),2641 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
...@@ -2649,7 +2672,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -2649,7 +2672,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
2649 const ptr_ty = sema.typeOf(ptr);2672 const ptr_ty = sema.typeOf(ptr);
2650 var ptr_info = ptr_ty.ptrInfo().data;2673 var ptr_info = ptr_ty.ptrInfo().data;
2651 ptr_info.mutable = false;2674 ptr_info.mutable = false;
2652 const const_ptr_ty = try Type.ptr(sema.arena, sema.mod.getTarget(), ptr_info);2675 const const_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_info);
26532676
2654 if (try sema.resolveMaybeUndefVal(block, inst_data.src(), ptr)) |val| {2677 if (try sema.resolveMaybeUndefVal(block, inst_data.src(), ptr)) |val| {
2655 return sema.addConstant(const_ptr_ty, val);2678 return sema.addConstant(const_ptr_ty, val);
...@@ -2669,7 +2692,7 @@ fn zirAllocInferredComptime(...@@ -2669,7 +2692,7 @@ fn zirAllocInferredComptime(
2669 return sema.addConstant(2692 return sema.addConstant(
2670 inferred_alloc_ty,2693 inferred_alloc_ty,
2671 try Value.Tag.inferred_alloc_comptime.create(sema.arena, .{2694 try Value.Tag.inferred_alloc_comptime.create(sema.arena, .{
2672 .decl = undefined,2695 .decl_index = undefined,
2673 .alignment = 0,2696 .alignment = 0,
2674 }),2697 }),
2675 );2698 );
...@@ -2687,7 +2710,7 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -2687,7 +2710,7 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
2687 return sema.analyzeComptimeAlloc(block, var_ty, 0, ty_src);2710 return sema.analyzeComptimeAlloc(block, var_ty, 0, ty_src);
2688 }2711 }
2689 const target = sema.mod.getTarget();2712 const target = sema.mod.getTarget();
2690 const ptr_type = try Type.ptr(sema.arena, target, .{2713 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
2691 .pointee_type = var_ty,2714 .pointee_type = var_ty,
2692 .@"addrspace" = target_util.defaultAddressSpace(target, .local),2715 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
2693 });2716 });
...@@ -2709,7 +2732,7 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -2709,7 +2732,7 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2709 }2732 }
2710 try sema.validateVarType(block, ty_src, var_ty, false);2733 try sema.validateVarType(block, ty_src, var_ty, false);
2711 const target = sema.mod.getTarget();2734 const target = sema.mod.getTarget();
2712 const ptr_type = try Type.ptr(sema.arena, target, .{2735 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
2713 .pointee_type = var_ty,2736 .pointee_type = var_ty,
2714 .@"addrspace" = target_util.defaultAddressSpace(target, .local),2737 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
2715 });2738 });
...@@ -2735,7 +2758,7 @@ fn zirAllocInferred(...@@ -2735,7 +2758,7 @@ fn zirAllocInferred(
2735 return sema.addConstant(2758 return sema.addConstant(
2736 inferred_alloc_ty,2759 inferred_alloc_ty,
2737 try Value.Tag.inferred_alloc_comptime.create(sema.arena, .{2760 try Value.Tag.inferred_alloc_comptime.create(sema.arena, .{
2738 .decl = undefined,2761 .decl_index = undefined,
2739 .alignment = 0,2762 .alignment = 0,
2740 }),2763 }),
2741 );2764 );
...@@ -2776,11 +2799,12 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -2776,11 +2799,12 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
2776 switch (ptr_val.tag()) {2799 switch (ptr_val.tag()) {
2777 .inferred_alloc_comptime => {2800 .inferred_alloc_comptime => {
2778 const iac = ptr_val.castTag(.inferred_alloc_comptime).?;2801 const iac = ptr_val.castTag(.inferred_alloc_comptime).?;
2779 const decl = iac.data.decl;2802 const decl_index = iac.data.decl_index;
2780 try sema.mod.declareDeclDependency(sema.owner_decl, decl);2803 try sema.mod.declareDeclDependency(sema.owner_decl_index, decl_index);
27812804
2805 const decl = sema.mod.declPtr(decl_index);
2782 const final_elem_ty = try decl.ty.copy(sema.arena);2806 const final_elem_ty = try decl.ty.copy(sema.arena);
2783 const final_ptr_ty = try Type.ptr(sema.arena, target, .{2807 const final_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
2784 .pointee_type = final_elem_ty,2808 .pointee_type = final_elem_ty,
2785 .mutable = var_is_mut,2809 .mutable = var_is_mut,
2786 .@"align" = iac.data.alignment,2810 .@"align" = iac.data.alignment,
...@@ -2791,11 +2815,11 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -2791,11 +2815,11 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
27912815
2792 if (var_is_mut) {2816 if (var_is_mut) {
2793 sema.air_values.items[value_index] = try Value.Tag.decl_ref_mut.create(sema.arena, .{2817 sema.air_values.items[value_index] = try Value.Tag.decl_ref_mut.create(sema.arena, .{
2794 .decl = decl,2818 .decl_index = decl_index,
2795 .runtime_index = block.runtime_index,2819 .runtime_index = block.runtime_index,
2796 });2820 });
2797 } else {2821 } else {
2798 sema.air_values.items[value_index] = try Value.Tag.decl_ref.create(sema.arena, decl);2822 sema.air_values.items[value_index] = try Value.Tag.decl_ref.create(sema.arena, decl_index);
2799 }2823 }
2800 },2824 },
2801 .inferred_alloc => {2825 .inferred_alloc => {
...@@ -2803,7 +2827,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -2803,7 +2827,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
2803 const peer_inst_list = inferred_alloc.data.stored_inst_list.items;2827 const peer_inst_list = inferred_alloc.data.stored_inst_list.items;
2804 const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_inst_list, .none);2828 const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_inst_list, .none);
28052829
2806 const final_ptr_ty = try Type.ptr(sema.arena, target, .{2830 const final_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
2807 .pointee_type = final_elem_ty,2831 .pointee_type = final_elem_ty,
2808 .mutable = var_is_mut,2832 .mutable = var_is_mut,
2809 .@"align" = inferred_alloc.data.alignment,2833 .@"align" = inferred_alloc.data.alignment,
...@@ -2873,22 +2897,22 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -2873,22 +2897,22 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
2873 if (store_op.lhs != Air.indexToRef(bitcast_inst)) break :ct;2897 if (store_op.lhs != Air.indexToRef(bitcast_inst)) break :ct;
2874 if (air_datas[bitcast_inst].ty_op.operand != Air.indexToRef(const_inst)) break :ct;2898 if (air_datas[bitcast_inst].ty_op.operand != Air.indexToRef(const_inst)) break :ct;
28752899
2876 const new_decl = d: {2900 const new_decl_index = d: {
2877 var anon_decl = try block.startAnonDecl(src);2901 var anon_decl = try block.startAnonDecl(src);
2878 defer anon_decl.deinit();2902 defer anon_decl.deinit();
2879 const new_decl = try anon_decl.finish(2903 const new_decl_index = try anon_decl.finish(
2880 try final_elem_ty.copy(anon_decl.arena()),2904 try final_elem_ty.copy(anon_decl.arena()),
2881 try store_val.copy(anon_decl.arena()),2905 try store_val.copy(anon_decl.arena()),
2882 inferred_alloc.data.alignment,2906 inferred_alloc.data.alignment,
2883 );2907 );
2884 break :d new_decl;2908 break :d new_decl_index;
2885 };2909 };
2886 try sema.mod.declareDeclDependency(sema.owner_decl, new_decl);2910 try sema.mod.declareDeclDependency(sema.owner_decl_index, new_decl_index);
28872911
2888 // Even though we reuse the constant instruction, we still remove it from the2912 // Even though we reuse the constant instruction, we still remove it from the
2889 // block so that codegen does not see it.2913 // block so that codegen does not see it.
2890 block.instructions.shrinkRetainingCapacity(block.instructions.items.len - 3);2914 block.instructions.shrinkRetainingCapacity(block.instructions.items.len - 3);
2891 sema.air_values.items[value_index] = try Value.Tag.decl_ref.create(sema.arena, new_decl);2915 sema.air_values.items[value_index] = try Value.Tag.decl_ref.create(sema.arena, new_decl_index);
2892 // if bitcast ty ref needs to be made const, make_ptr_const2916 // if bitcast ty ref needs to be made const, make_ptr_const
2893 // ZIR handles it later, so we can just use the ty ref here.2917 // ZIR handles it later, so we can just use the ty ref here.
2894 air_datas[ptr_inst].ty_pl.ty = air_datas[bitcast_inst].ty_op.ty;2918 air_datas[ptr_inst].ty_pl.ty = air_datas[bitcast_inst].ty_op.ty;
...@@ -3218,10 +3242,11 @@ fn validateStructInit(...@@ -3218,10 +3242,11 @@ fn validateStructInit(
3218 }3242 }
32193243
3220 if (root_msg) |msg| {3244 if (root_msg) |msg| {
3221 const fqn = try struct_obj.getFullyQualifiedName(gpa);3245 const mod = sema.mod;
3246 const fqn = try struct_obj.getFullyQualifiedName(mod);
3222 defer gpa.free(fqn);3247 defer gpa.free(fqn);
3223 try sema.mod.errNoteNonLazy(3248 try mod.errNoteNonLazy(
3224 struct_obj.srcLoc(),3249 struct_obj.srcLoc(mod),
3225 msg,3250 msg,
3226 "struct '{s}' declared here",3251 "struct '{s}' declared here",
3227 .{fqn},3252 .{fqn},
...@@ -3325,10 +3350,10 @@ fn validateStructInit(...@@ -3325,10 +3350,10 @@ fn validateStructInit(
3325 }3350 }
33263351
3327 if (root_msg) |msg| {3352 if (root_msg) |msg| {
3328 const fqn = try struct_obj.getFullyQualifiedName(gpa);3353 const fqn = try struct_obj.getFullyQualifiedName(sema.mod);
3329 defer gpa.free(fqn);3354 defer gpa.free(fqn);
3330 try sema.mod.errNoteNonLazy(3355 try sema.mod.errNoteNonLazy(
3331 struct_obj.srcLoc(),3356 struct_obj.srcLoc(sema.mod),
3332 msg,3357 msg,
3333 "struct '{s}' declared here",3358 "struct '{s}' declared here",
3334 .{fqn},3359 .{fqn},
...@@ -3497,9 +3522,8 @@ fn failWithBadMemberAccess(...@@ -3497,9 +3522,8 @@ fn failWithBadMemberAccess(
3497 else => unreachable,3522 else => unreachable,
3498 };3523 };
3499 const msg = msg: {3524 const msg = msg: {
3500 const target = sema.mod.getTarget();
3501 const msg = try sema.errMsg(block, field_src, "{s} '{}' has no member named '{s}'", .{3525 const msg = try sema.errMsg(block, field_src, "{s} '{}' has no member named '{s}'", .{
3502 kw_name, agg_ty.fmt(target), field_name,3526 kw_name, agg_ty.fmt(sema.mod), field_name,
3503 });3527 });
3504 errdefer msg.destroy(sema.gpa);3528 errdefer msg.destroy(sema.gpa);
3505 try sema.addDeclaredHereNote(msg, agg_ty);3529 try sema.addDeclaredHereNote(msg, agg_ty);
...@@ -3517,7 +3541,7 @@ fn failWithBadStructFieldAccess(...@@ -3517,7 +3541,7 @@ fn failWithBadStructFieldAccess(
3517) CompileError {3541) CompileError {
3518 const gpa = sema.gpa;3542 const gpa = sema.gpa;
35193543
3520 const fqn = try struct_obj.getFullyQualifiedName(gpa);3544 const fqn = try struct_obj.getFullyQualifiedName(sema.mod);
3521 defer gpa.free(fqn);3545 defer gpa.free(fqn);
35223546
3523 const msg = msg: {3547 const msg = msg: {
...@@ -3528,7 +3552,7 @@ fn failWithBadStructFieldAccess(...@@ -3528,7 +3552,7 @@ fn failWithBadStructFieldAccess(
3528 .{ field_name, fqn },3552 .{ field_name, fqn },
3529 );3553 );
3530 errdefer msg.destroy(gpa);3554 errdefer msg.destroy(gpa);
3531 try sema.mod.errNoteNonLazy(struct_obj.srcLoc(), msg, "struct declared here", .{});3555 try sema.mod.errNoteNonLazy(struct_obj.srcLoc(sema.mod), msg, "struct declared here", .{});
3532 break :msg msg;3556 break :msg msg;
3533 };3557 };
3534 return sema.failWithOwnedErrorMsg(block, msg);3558 return sema.failWithOwnedErrorMsg(block, msg);
...@@ -3543,7 +3567,7 @@ fn failWithBadUnionFieldAccess(...@@ -3543,7 +3567,7 @@ fn failWithBadUnionFieldAccess(
3543) CompileError {3567) CompileError {
3544 const gpa = sema.gpa;3568 const gpa = sema.gpa;
35453569
3546 const fqn = try union_obj.getFullyQualifiedName(gpa);3570 const fqn = try union_obj.getFullyQualifiedName(sema.mod);
3547 defer gpa.free(fqn);3571 defer gpa.free(fqn);
35483572
3549 const msg = msg: {3573 const msg = msg: {
...@@ -3554,14 +3578,14 @@ fn failWithBadUnionFieldAccess(...@@ -3554,14 +3578,14 @@ fn failWithBadUnionFieldAccess(
3554 .{ field_name, fqn },3578 .{ field_name, fqn },
3555 );3579 );
3556 errdefer msg.destroy(gpa);3580 errdefer msg.destroy(gpa);
3557 try sema.mod.errNoteNonLazy(union_obj.srcLoc(), msg, "union declared here", .{});3581 try sema.mod.errNoteNonLazy(union_obj.srcLoc(sema.mod), msg, "union declared here", .{});
3558 break :msg msg;3582 break :msg msg;
3559 };3583 };
3560 return sema.failWithOwnedErrorMsg(block, msg);3584 return sema.failWithOwnedErrorMsg(block, msg);
3561}3585}
35623586
3563fn addDeclaredHereNote(sema: *Sema, parent: *Module.ErrorMsg, decl_ty: Type) !void {3587fn addDeclaredHereNote(sema: *Sema, parent: *Module.ErrorMsg, decl_ty: Type) !void {
3564 const src_loc = decl_ty.declSrcLocOrNull() orelse return;3588 const src_loc = decl_ty.declSrcLocOrNull(sema.mod) orelse return;
3565 const category = switch (decl_ty.zigTypeTag()) {3589 const category = switch (decl_ty.zigTypeTag()) {
3566 .Union => "union",3590 .Union => "union",
3567 .Struct => "struct",3591 .Struct => "struct",
...@@ -3645,7 +3669,7 @@ fn storeToInferredAlloc(...@@ -3645,7 +3669,7 @@ fn storeToInferredAlloc(
3645 try inferred_alloc.data.stored_inst_list.append(sema.arena, operand);3669 try inferred_alloc.data.stored_inst_list.append(sema.arena, operand);
3646 // Create a runtime bitcast instruction with exactly the type the pointer wants.3670 // Create a runtime bitcast instruction with exactly the type the pointer wants.
3647 const target = sema.mod.getTarget();3671 const target = sema.mod.getTarget();
3648 const ptr_ty = try Type.ptr(sema.arena, target, .{3672 const ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
3649 .pointee_type = operand_ty,3673 .pointee_type = operand_ty,
3650 .@"align" = inferred_alloc.data.alignment,3674 .@"align" = inferred_alloc.data.alignment,
3651 .@"addrspace" = target_util.defaultAddressSpace(target, .local),3675 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
...@@ -3670,7 +3694,7 @@ fn storeToInferredAllocComptime(...@@ -3670,7 +3694,7 @@ fn storeToInferredAllocComptime(
3670 }3694 }
3671 var anon_decl = try block.startAnonDecl(src);3695 var anon_decl = try block.startAnonDecl(src);
3672 defer anon_decl.deinit();3696 defer anon_decl.deinit();
3673 iac.data.decl = try anon_decl.finish(3697 iac.data.decl_index = try anon_decl.finish(
3674 try operand_ty.copy(anon_decl.arena()),3698 try operand_ty.copy(anon_decl.arena()),
3675 try operand_val.copy(anon_decl.arena()),3699 try operand_val.copy(anon_decl.arena()),
3676 iac.data.alignment,3700 iac.data.alignment,
...@@ -3869,7 +3893,6 @@ fn zirCompileLog(...@@ -3869,7 +3893,6 @@ fn zirCompileLog(
3869 const src_node = extra.data.src_node;3893 const src_node = extra.data.src_node;
3870 const src: LazySrcLoc = .{ .node_offset = src_node };3894 const src: LazySrcLoc = .{ .node_offset = src_node };
3871 const args = sema.code.refSlice(extra.end, extended.small);3895 const args = sema.code.refSlice(extra.end, extended.small);
3872 const target = sema.mod.getTarget();
38733896
3874 for (args) |arg_ref, i| {3897 for (args) |arg_ref, i| {
3875 if (i != 0) try writer.print(", ", .{});3898 if (i != 0) try writer.print(", ", .{});
...@@ -3878,15 +3901,15 @@ fn zirCompileLog(...@@ -3878,15 +3901,15 @@ fn zirCompileLog(
3878 const arg_ty = sema.typeOf(arg);3901 const arg_ty = sema.typeOf(arg);
3879 if (try sema.resolveMaybeUndefVal(block, src, arg)) |val| {3902 if (try sema.resolveMaybeUndefVal(block, src, arg)) |val| {
3880 try writer.print("@as({}, {})", .{3903 try writer.print("@as({}, {})", .{
3881 arg_ty.fmt(target), val.fmtValue(arg_ty, target),3904 arg_ty.fmt(sema.mod), val.fmtValue(arg_ty, sema.mod),
3882 });3905 });
3883 } else {3906 } else {
3884 try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(target)});3907 try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(sema.mod)});
3885 }3908 }
3886 }3909 }
3887 try writer.print("\n", .{});3910 try writer.print("\n", .{});
38883911
3889 const gop = try sema.mod.compile_log_decls.getOrPut(sema.gpa, sema.owner_decl);3912 const gop = try sema.mod.compile_log_decls.getOrPut(sema.gpa, sema.owner_decl_index);
3890 if (!gop.found_existing) {3913 if (!gop.found_existing) {
3891 gop.value_ptr.* = src_node;3914 gop.value_ptr.* = src_node;
3892 }3915 }
...@@ -3996,7 +4019,8 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -3996,7 +4019,8 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
3996 // Ignore the result, all the relevant operations have written to c_import_buf already.4019 // Ignore the result, all the relevant operations have written to c_import_buf already.
3997 _ = try sema.analyzeBodyBreak(&child_block, body);4020 _ = try sema.analyzeBodyBreak(&child_block, body);
39984021
3999 const c_import_res = sema.mod.comp.cImport(c_import_buf.items) catch |err|4022 const mod = sema.mod;
4023 const c_import_res = mod.comp.cImport(c_import_buf.items) catch |err|
4000 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});4024 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
40014025
4002 if (c_import_res.errors.len != 0) {4026 if (c_import_res.errors.len != 0) {
...@@ -4004,12 +4028,12 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -4004,12 +4028,12 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
4004 const msg = try sema.errMsg(&child_block, src, "C import failed", .{});4028 const msg = try sema.errMsg(&child_block, src, "C import failed", .{});
4005 errdefer msg.destroy(sema.gpa);4029 errdefer msg.destroy(sema.gpa);
40064030
4007 if (!sema.mod.comp.bin_file.options.link_libc)4031 if (!mod.comp.bin_file.options.link_libc)
4008 try sema.errNote(&child_block, src, msg, "libc headers not available; compilation does not link against libc", .{});4032 try sema.errNote(&child_block, src, msg, "libc headers not available; compilation does not link against libc", .{});
40094033
4010 for (c_import_res.errors) |_| {4034 for (c_import_res.errors) |_| {
4011 // TODO integrate with LazySrcLoc4035 // TODO integrate with LazySrcLoc
4012 // try sema.mod.errNoteNonLazy(.{}, msg, "{s}", .{clang_err.msg_ptr[0..clang_err.msg_len]});4036 // try mod.errNoteNonLazy(.{}, msg, "{s}", .{clang_err.msg_ptr[0..clang_err.msg_len]});
4013 // if (clang_err.filename_ptr) |p| p[0..clang_err.filename_len] else "(no file)",4037 // if (clang_err.filename_ptr) |p| p[0..clang_err.filename_len] else "(no file)",
4014 // clang_err.line + 1,4038 // clang_err.line + 1,
4015 // clang_err.column + 1,4039 // clang_err.column + 1,
...@@ -4027,20 +4051,21 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -4027,20 +4051,21 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
4027 error.OutOfMemory => return error.OutOfMemory,4051 error.OutOfMemory => return error.OutOfMemory,
4028 else => unreachable, // we pass null for root_src_dir_path4052 else => unreachable, // we pass null for root_src_dir_path
4029 };4053 };
4030 const std_pkg = sema.mod.main_pkg.table.get("std").?;4054 const std_pkg = mod.main_pkg.table.get("std").?;
4031 const builtin_pkg = sema.mod.main_pkg.table.get("builtin").?;4055 const builtin_pkg = mod.main_pkg.table.get("builtin").?;
4032 try c_import_pkg.add(sema.gpa, "builtin", builtin_pkg);4056 try c_import_pkg.add(sema.gpa, "builtin", builtin_pkg);
4033 try c_import_pkg.add(sema.gpa, "std", std_pkg);4057 try c_import_pkg.add(sema.gpa, "std", std_pkg);
40344058
4035 const result = sema.mod.importPkg(c_import_pkg) catch |err|4059 const result = mod.importPkg(c_import_pkg) catch |err|
4036 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});4060 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
40374061
4038 sema.mod.astGenFile(result.file) catch |err|4062 mod.astGenFile(result.file) catch |err|
4039 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});4063 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
40404064
4041 try sema.mod.semaFile(result.file);4065 try mod.semaFile(result.file);
4042 const file_root_decl = result.file.root_decl.?;4066 const file_root_decl_index = result.file.root_decl.unwrap().?;
4043 try sema.mod.declareDeclDependency(sema.owner_decl, file_root_decl);4067 const file_root_decl = mod.declPtr(file_root_decl_index);
4068 try mod.declareDeclDependency(sema.owner_decl_index, file_root_decl_index);
4044 return sema.addConstant(file_root_decl.ty, file_root_decl.val);4069 return sema.addConstant(file_root_decl.ty, file_root_decl.val);
4045}4070}
40464071
...@@ -4139,6 +4164,7 @@ fn analyzeBlockBody(...@@ -4139,6 +4164,7 @@ fn analyzeBlockBody(
4139 defer tracy.end();4164 defer tracy.end();
41404165
4141 const gpa = sema.gpa;4166 const gpa = sema.gpa;
4167 const mod = sema.mod;
41424168
4143 // Blocks must terminate with noreturn instruction.4169 // Blocks must terminate with noreturn instruction.
4144 assert(child_block.instructions.items.len != 0);4170 assert(child_block.instructions.items.len != 0);
...@@ -4173,16 +4199,16 @@ fn analyzeBlockBody(...@@ -4173,16 +4199,16 @@ fn analyzeBlockBody(
41734199
4174 const type_src = src; // TODO: better source location4200 const type_src = src; // TODO: better source location
4175 const valid_rt = try sema.validateRunTimeType(child_block, type_src, resolved_ty, false);4201 const valid_rt = try sema.validateRunTimeType(child_block, type_src, resolved_ty, false);
4176 const target = sema.mod.getTarget();
4177 if (!valid_rt) {4202 if (!valid_rt) {
4178 const msg = msg: {4203 const msg = msg: {
4179 const msg = try sema.errMsg(child_block, type_src, "value with comptime only type '{}' depends on runtime control flow", .{resolved_ty.fmt(target)});4204 const msg = try sema.errMsg(child_block, type_src, "value with comptime only type '{}' depends on runtime control flow", .{resolved_ty.fmt(mod)});
4180 errdefer msg.destroy(sema.gpa);4205 errdefer msg.destroy(sema.gpa);
41814206
4182 const runtime_src = child_block.runtime_cond orelse child_block.runtime_loop.?;4207 const runtime_src = child_block.runtime_cond orelse child_block.runtime_loop.?;
4183 try sema.errNote(child_block, runtime_src, msg, "runtime control flow here", .{});4208 try sema.errNote(child_block, runtime_src, msg, "runtime control flow here", .{});
41844209
4185 try sema.explainWhyTypeIsComptime(child_block, type_src, msg, type_src.toSrcLoc(child_block.src_decl), resolved_ty);4210 const child_src_decl = mod.declPtr(child_block.src_decl);
4211 try sema.explainWhyTypeIsComptime(child_block, type_src, msg, type_src.toSrcLoc(child_src_decl), resolved_ty);
41864212
4187 break :msg msg;4213 break :msg msg;
4188 };4214 };
...@@ -4204,7 +4230,7 @@ fn analyzeBlockBody(...@@ -4204,7 +4230,7 @@ fn analyzeBlockBody(
4204 const br_operand = sema.air_instructions.items(.data)[br].br.operand;4230 const br_operand = sema.air_instructions.items(.data)[br].br.operand;
4205 const br_operand_src = src;4231 const br_operand_src = src;
4206 const br_operand_ty = sema.typeOf(br_operand);4232 const br_operand_ty = sema.typeOf(br_operand);
4207 if (br_operand_ty.eql(resolved_ty, target)) {4233 if (br_operand_ty.eql(resolved_ty, mod)) {
4208 // No type coercion needed.4234 // No type coercion needed.
4209 continue;4235 continue;
4210 }4236 }
...@@ -4262,9 +4288,9 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -4262,9 +4288,9 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
4262 if (extra.namespace != .none) {4288 if (extra.namespace != .none) {
4263 return sema.fail(block, src, "TODO: implement exporting with field access", .{});4289 return sema.fail(block, src, "TODO: implement exporting with field access", .{});
4264 }4290 }
4265 const decl = try sema.lookupIdentifier(block, operand_src, decl_name);4291 const decl_index = try sema.lookupIdentifier(block, operand_src, decl_name);
4266 const options = try sema.resolveExportOptions(block, options_src, extra.options);4292 const options = try sema.resolveExportOptions(block, options_src, extra.options);
4267 try sema.analyzeExport(block, src, options, decl);4293 try sema.analyzeExport(block, src, options, decl_index);
4268}4294}
42694295
4270fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {4296fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
...@@ -4278,11 +4304,11 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -4278,11 +4304,11 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
4278 const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };4304 const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
4279 const operand = try sema.resolveInstConst(block, operand_src, extra.operand);4305 const operand = try sema.resolveInstConst(block, operand_src, extra.operand);
4280 const options = try sema.resolveExportOptions(block, options_src, extra.options);4306 const options = try sema.resolveExportOptions(block, options_src, extra.options);
4281 const decl = switch (operand.val.tag()) {4307 const decl_index = switch (operand.val.tag()) {
4282 .function => operand.val.castTag(.function).?.data.owner_decl,4308 .function => operand.val.castTag(.function).?.data.owner_decl,
4283 else => return sema.fail(block, operand_src, "TODO implement exporting arbitrary Value objects", .{}), // TODO put this Value into an anonymous Decl and then export it.4309 else => return sema.fail(block, operand_src, "TODO implement exporting arbitrary Value objects", .{}), // TODO put this Value into an anonymous Decl and then export it.
4284 };4310 };
4285 try sema.analyzeExport(block, src, options, decl);4311 try sema.analyzeExport(block, src, options, decl_index);
4286}4312}
42874313
4288pub fn analyzeExport(4314pub fn analyzeExport(
...@@ -4290,18 +4316,18 @@ pub fn analyzeExport(...@@ -4290,18 +4316,18 @@ pub fn analyzeExport(
4290 block: *Block,4316 block: *Block,
4291 src: LazySrcLoc,4317 src: LazySrcLoc,
4292 borrowed_options: std.builtin.ExportOptions,4318 borrowed_options: std.builtin.ExportOptions,
4293 exported_decl: *Decl,4319 exported_decl_index: Decl.Index,
4294) !void {4320) !void {
4295 const Export = Module.Export;4321 const Export = Module.Export;
4296 const mod = sema.mod;4322 const mod = sema.mod;
4297 const target = mod.getTarget();
42984323
4299 try mod.ensureDeclAnalyzed(exported_decl);4324 try mod.ensureDeclAnalyzed(exported_decl_index);
4325 const exported_decl = mod.declPtr(exported_decl_index);
4300 // TODO run the same checks as we do for C ABI struct fields4326 // TODO run the same checks as we do for C ABI struct fields
4301 switch (exported_decl.ty.zigTypeTag()) {4327 switch (exported_decl.ty.zigTypeTag()) {
4302 .Fn, .Int, .Enum, .Struct, .Union, .Array, .Float => {},4328 .Fn, .Int, .Enum, .Struct, .Union, .Array, .Float => {},
4303 else => return sema.fail(block, src, "unable to export type '{}'", .{4329 else => return sema.fail(block, src, "unable to export type '{}'", .{
4304 exported_decl.ty.fmt(target),4330 exported_decl.ty.fmt(sema.mod),
4305 }),4331 }),
4306 }4332 }
43074333
...@@ -4319,13 +4345,6 @@ pub fn analyzeExport(...@@ -4319,13 +4345,6 @@ pub fn analyzeExport(
4319 const section: ?[]const u8 = if (borrowed_options.section) |s| try gpa.dupe(u8, s) else null;4345 const section: ?[]const u8 = if (borrowed_options.section) |s| try gpa.dupe(u8, s) else null;
4320 errdefer if (section) |s| gpa.free(s);4346 errdefer if (section) |s| gpa.free(s);
43214347
4322 const src_decl = block.src_decl;
4323 const owner_decl = sema.owner_decl;
4324
4325 log.debug("exporting Decl '{s}' as symbol '{s}' from Decl '{s}'", .{
4326 exported_decl.name, symbol_name, owner_decl.name,
4327 });
4328
4329 new_export.* = .{4348 new_export.* = .{
4330 .options = .{4349 .options = .{
4331 .name = symbol_name,4350 .name = symbol_name,
...@@ -4343,14 +4362,14 @@ pub fn analyzeExport(...@@ -4343,14 +4362,14 @@ pub fn analyzeExport(
4343 .spirv => .{ .spirv = {} },4362 .spirv => .{ .spirv = {} },
4344 .nvptx => .{ .nvptx = {} },4363 .nvptx => .{ .nvptx = {} },
4345 },4364 },
4346 .owner_decl = owner_decl,4365 .owner_decl = sema.owner_decl_index,
4347 .src_decl = src_decl,4366 .src_decl = block.src_decl,
4348 .exported_decl = exported_decl,4367 .exported_decl = exported_decl_index,
4349 .status = .in_progress,4368 .status = .in_progress,
4350 };4369 };
43514370
4352 // Add to export_owners table.4371 // Add to export_owners table.
4353 const eo_gop = mod.export_owners.getOrPutAssumeCapacity(owner_decl);4372 const eo_gop = mod.export_owners.getOrPutAssumeCapacity(sema.owner_decl_index);
4354 if (!eo_gop.found_existing) {4373 if (!eo_gop.found_existing) {
4355 eo_gop.value_ptr.* = &[0]*Export{};4374 eo_gop.value_ptr.* = &[0]*Export{};
4356 }4375 }
...@@ -4359,7 +4378,7 @@ pub fn analyzeExport(...@@ -4359,7 +4378,7 @@ pub fn analyzeExport(
4359 errdefer eo_gop.value_ptr.* = gpa.shrink(eo_gop.value_ptr.*, eo_gop.value_ptr.len - 1);4378 errdefer eo_gop.value_ptr.* = gpa.shrink(eo_gop.value_ptr.*, eo_gop.value_ptr.len - 1);
43604379
4361 // Add to exported_decl table.4380 // Add to exported_decl table.
4362 const de_gop = mod.decl_exports.getOrPutAssumeCapacity(exported_decl);4381 const de_gop = mod.decl_exports.getOrPutAssumeCapacity(exported_decl_index);
4363 if (!de_gop.found_existing) {4382 if (!de_gop.found_existing) {
4364 de_gop.value_ptr.* = &[0]*Export{};4383 de_gop.value_ptr.* = &[0]*Export{};
4365 }4384 }
...@@ -4381,7 +4400,8 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -4381,7 +4400,8 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
4381 const func = sema.owner_func orelse4400 const func = sema.owner_func orelse
4382 return sema.fail(block, src, "@setAlignStack outside function body", .{});4401 return sema.fail(block, src, "@setAlignStack outside function body", .{});
43834402
4384 switch (func.owner_decl.ty.fnCallingConvention()) {4403 const fn_owner_decl = sema.mod.declPtr(func.owner_decl);
4404 switch (fn_owner_decl.ty.fnCallingConvention()) {
4385 .Naked => return sema.fail(block, src, "@setAlignStack in naked function", .{}),4405 .Naked => return sema.fail(block, src, "@setAlignStack in naked function", .{}),
4386 .Inline => return sema.fail(block, src, "@setAlignStack in inline function", .{}),4406 .Inline => return sema.fail(block, src, "@setAlignStack in inline function", .{}),
4387 else => {},4407 else => {},
...@@ -4561,8 +4581,8 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -4561,8 +4581,8 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
4561 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;4581 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
4562 const src = inst_data.src();4582 const src = inst_data.src();
4563 const decl_name = inst_data.get(sema.code);4583 const decl_name = inst_data.get(sema.code);
4564 const decl = try sema.lookupIdentifier(block, src, decl_name);4584 const decl_index = try sema.lookupIdentifier(block, src, decl_name);
4565 return sema.analyzeDeclRef(decl);4585 return sema.analyzeDeclRef(decl_index);
4566}4586}
45674587
4568fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {4588fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -4573,11 +4593,11 @@ fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -4573,11 +4593,11 @@ fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
4573 return sema.analyzeDeclVal(block, src, decl);4593 return sema.analyzeDeclVal(block, src, decl);
4574}4594}
45754595
4576fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: []const u8) !*Decl {4596fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: []const u8) !Decl.Index {
4577 var namespace = block.namespace;4597 var namespace = block.namespace;
4578 while (true) {4598 while (true) {
4579 if (try sema.lookupInNamespace(block, src, namespace, name, false)) |decl| {4599 if (try sema.lookupInNamespace(block, src, namespace, name, false)) |decl_index| {
4580 return decl;4600 return decl_index;
4581 }4601 }
4582 namespace = namespace.parent orelse break;4602 namespace = namespace.parent orelse break;
4583 }4603 }
...@@ -4593,12 +4613,13 @@ fn lookupInNamespace(...@@ -4593,12 +4613,13 @@ fn lookupInNamespace(
4593 namespace: *Namespace,4613 namespace: *Namespace,
4594 ident_name: []const u8,4614 ident_name: []const u8,
4595 observe_usingnamespace: bool,4615 observe_usingnamespace: bool,
4596) CompileError!?*Decl {4616) CompileError!?Decl.Index {
4597 const mod = sema.mod;4617 const mod = sema.mod;
45984618
4599 const namespace_decl = namespace.getDecl();4619 const namespace_decl_index = namespace.getDeclIndex();
4620 const namespace_decl = sema.mod.declPtr(namespace_decl_index);
4600 if (namespace_decl.analysis == .file_failure) {4621 if (namespace_decl.analysis == .file_failure) {
4601 try mod.declareDeclDependency(sema.owner_decl, namespace_decl);4622 try mod.declareDeclDependency(sema.owner_decl_index, namespace_decl_index);
4602 return error.AnalysisFail;4623 return error.AnalysisFail;
4603 }4624 }
46044625
...@@ -4610,7 +4631,7 @@ fn lookupInNamespace(...@@ -4610,7 +4631,7 @@ fn lookupInNamespace(
4610 defer checked_namespaces.deinit(gpa);4631 defer checked_namespaces.deinit(gpa);
46114632
4612 // Keep track of name conflicts for error notes.4633 // Keep track of name conflicts for error notes.
4613 var candidates: std.ArrayListUnmanaged(*Decl) = .{};4634 var candidates: std.ArrayListUnmanaged(Decl.Index) = .{};
4614 defer candidates.deinit(gpa);4635 defer candidates.deinit(gpa);
46154636
4616 try checked_namespaces.put(gpa, namespace, {});4637 try checked_namespaces.put(gpa, namespace, {});
...@@ -4618,23 +4639,25 @@ fn lookupInNamespace(...@@ -4618,23 +4639,25 @@ fn lookupInNamespace(
46184639
4619 while (check_i < checked_namespaces.count()) : (check_i += 1) {4640 while (check_i < checked_namespaces.count()) : (check_i += 1) {
4620 const check_ns = checked_namespaces.keys()[check_i];4641 const check_ns = checked_namespaces.keys()[check_i];
4621 if (check_ns.decls.getKeyAdapted(ident_name, Module.DeclAdapter{})) |decl| {4642 if (check_ns.decls.getKeyAdapted(ident_name, Module.DeclAdapter{ .mod = mod })) |decl_index| {
4622 // Skip decls which are not marked pub, which are in a different4643 // Skip decls which are not marked pub, which are in a different
4623 // file than the `a.b`/`@hasDecl` syntax.4644 // file than the `a.b`/`@hasDecl` syntax.
4645 const decl = mod.declPtr(decl_index);
4624 if (decl.is_pub or src_file == decl.getFileScope()) {4646 if (decl.is_pub or src_file == decl.getFileScope()) {
4625 try candidates.append(gpa, decl);4647 try candidates.append(gpa, decl_index);
4626 }4648 }
4627 }4649 }
4628 var it = check_ns.usingnamespace_set.iterator();4650 var it = check_ns.usingnamespace_set.iterator();
4629 while (it.next()) |entry| {4651 while (it.next()) |entry| {
4630 const sub_usingnamespace_decl = entry.key_ptr.*;4652 const sub_usingnamespace_decl_index = entry.key_ptr.*;
4653 const sub_usingnamespace_decl = mod.declPtr(sub_usingnamespace_decl_index);
4631 const sub_is_pub = entry.value_ptr.*;4654 const sub_is_pub = entry.value_ptr.*;
4632 if (!sub_is_pub and src_file != sub_usingnamespace_decl.getFileScope()) {4655 if (!sub_is_pub and src_file != sub_usingnamespace_decl.getFileScope()) {
4633 // Skip usingnamespace decls which are not marked pub, which are in4656 // Skip usingnamespace decls which are not marked pub, which are in
4634 // a different file than the `a.b`/`@hasDecl` syntax.4657 // a different file than the `a.b`/`@hasDecl` syntax.
4635 continue;4658 continue;
4636 }4659 }
4637 try sema.ensureDeclAnalyzed(sub_usingnamespace_decl);4660 try sema.ensureDeclAnalyzed(sub_usingnamespace_decl_index);
4638 const ns_ty = sub_usingnamespace_decl.val.castTag(.ty).?.data;4661 const ns_ty = sub_usingnamespace_decl.val.castTag(.ty).?.data;
4639 const sub_ns = ns_ty.getNamespace().?;4662 const sub_ns = ns_ty.getNamespace().?;
4640 try checked_namespaces.put(gpa, sub_ns, {});4663 try checked_namespaces.put(gpa, sub_ns, {});
...@@ -4644,15 +4667,16 @@ fn lookupInNamespace(...@@ -4644,15 +4667,16 @@ fn lookupInNamespace(
4644 switch (candidates.items.len) {4667 switch (candidates.items.len) {
4645 0 => {},4668 0 => {},
4646 1 => {4669 1 => {
4647 const decl = candidates.items[0];4670 const decl_index = candidates.items[0];
4648 try mod.declareDeclDependency(sema.owner_decl, decl);4671 try mod.declareDeclDependency(sema.owner_decl_index, decl_index);
4649 return decl;4672 return decl_index;
4650 },4673 },
4651 else => {4674 else => {
4652 const msg = msg: {4675 const msg = msg: {
4653 const msg = try sema.errMsg(block, src, "ambiguous reference", .{});4676 const msg = try sema.errMsg(block, src, "ambiguous reference", .{});
4654 errdefer msg.destroy(gpa);4677 errdefer msg.destroy(gpa);
4655 for (candidates.items) |candidate| {4678 for (candidates.items) |candidate_index| {
4679 const candidate = mod.declPtr(candidate_index);
4656 const src_loc = candidate.srcLoc();4680 const src_loc = candidate.srcLoc();
4657 try mod.errNoteNonLazy(src_loc, msg, "declared here", .{});4681 try mod.errNoteNonLazy(src_loc, msg, "declared here", .{});
4658 }4682 }
...@@ -4661,9 +4685,9 @@ fn lookupInNamespace(...@@ -4661,9 +4685,9 @@ fn lookupInNamespace(
4661 return sema.failWithOwnedErrorMsg(block, msg);4685 return sema.failWithOwnedErrorMsg(block, msg);
4662 },4686 },
4663 }4687 }
4664 } else if (namespace.decls.getKeyAdapted(ident_name, Module.DeclAdapter{})) |decl| {4688 } else if (namespace.decls.getKeyAdapted(ident_name, Module.DeclAdapter{ .mod = mod })) |decl_index| {
4665 try mod.declareDeclDependency(sema.owner_decl, decl);4689 try mod.declareDeclDependency(sema.owner_decl_index, decl_index);
4666 return decl;4690 return decl_index;
4667 }4691 }
46684692
4669 log.debug("{*} ({s}) depends on non-existence of '{s}' in {*} ({s})", .{4693 log.debug("{*} ({s}) depends on non-existence of '{s}' in {*} ({s})", .{
...@@ -4672,7 +4696,7 @@ fn lookupInNamespace(...@@ -4672,7 +4696,7 @@ fn lookupInNamespace(
4672 // TODO This dependency is too strong. Really, it should only be a dependency4696 // TODO This dependency is too strong. Really, it should only be a dependency
4673 // on the non-existence of `ident_name` in the namespace. We can lessen the number of4697 // on the non-existence of `ident_name` in the namespace. We can lessen the number of
4674 // outdated declarations by making this dependency more sophisticated.4698 // outdated declarations by making this dependency more sophisticated.
4675 try mod.declareDeclDependency(sema.owner_decl, namespace_decl);4699 try mod.declareDeclDependency(sema.owner_decl_index, namespace_decl_index);
4676 return null;4700 return null;
4677}4701}
46784702
...@@ -4725,13 +4749,14 @@ const GenericCallAdapter = struct {...@@ -4725,13 +4749,14 @@ const GenericCallAdapter = struct {
4725 /// Unlike comptime_args, the Type here is not always present.4749 /// Unlike comptime_args, the Type here is not always present.
4726 /// .generic_poison is used to communicate non-anytype parameters.4750 /// .generic_poison is used to communicate non-anytype parameters.
4727 comptime_tvs: []const TypedValue,4751 comptime_tvs: []const TypedValue,
4728 target: std.Target,4752 module: *Module,
47294753
4730 pub fn eql(ctx: @This(), adapted_key: void, other_key: *Module.Fn) bool {4754 pub fn eql(ctx: @This(), adapted_key: void, other_key: *Module.Fn) bool {
4731 _ = adapted_key;4755 _ = adapted_key;
4732 // The generic function Decl is guaranteed to be the first dependency4756 // The generic function Decl is guaranteed to be the first dependency
4733 // of each of its instantiations.4757 // of each of its instantiations.
4734 const generic_owner_decl = other_key.owner_decl.dependencies.keys()[0];4758 const other_owner_decl = ctx.module.declPtr(other_key.owner_decl);
4759 const generic_owner_decl = other_owner_decl.dependencies.keys()[0];
4735 if (ctx.generic_fn.owner_decl != generic_owner_decl) return false;4760 if (ctx.generic_fn.owner_decl != generic_owner_decl) return false;
47364761
4737 const other_comptime_args = other_key.comptime_args.?;4762 const other_comptime_args = other_key.comptime_args.?;
...@@ -4747,18 +4772,18 @@ const GenericCallAdapter = struct {...@@ -4747,18 +4772,18 @@ const GenericCallAdapter = struct {
47474772
4748 if (this_is_anytype) {4773 if (this_is_anytype) {
4749 // Both are anytype parameters.4774 // Both are anytype parameters.
4750 if (!this_arg.ty.eql(other_arg.ty, ctx.target)) {4775 if (!this_arg.ty.eql(other_arg.ty, ctx.module)) {
4751 return false;4776 return false;
4752 }4777 }
4753 if (this_is_comptime) {4778 if (this_is_comptime) {
4754 // Both are comptime and anytype parameters with matching types.4779 // Both are comptime and anytype parameters with matching types.
4755 if (!this_arg.val.eql(other_arg.val, other_arg.ty, ctx.target)) {4780 if (!this_arg.val.eql(other_arg.val, other_arg.ty, ctx.module)) {
4756 return false;4781 return false;
4757 }4782 }
4758 }4783 }
4759 } else if (this_is_comptime) {4784 } else if (this_is_comptime) {
4760 // Both are comptime parameters but not anytype parameters.4785 // Both are comptime parameters but not anytype parameters.
4761 if (!this_arg.val.eql(other_arg.val, other_arg.ty, ctx.target)) {4786 if (!this_arg.val.eql(other_arg.val, other_arg.ty, ctx.module)) {
4762 return false;4787 return false;
4763 }4788 }
4764 }4789 }
...@@ -4787,7 +4812,6 @@ fn analyzeCall(...@@ -4787,7 +4812,6 @@ fn analyzeCall(
4787 const mod = sema.mod;4812 const mod = sema.mod;
47884813
4789 const callee_ty = sema.typeOf(func);4814 const callee_ty = sema.typeOf(func);
4790 const target = sema.mod.getTarget();
4791 const func_ty = func_ty: {4815 const func_ty = func_ty: {
4792 switch (callee_ty.zigTypeTag()) {4816 switch (callee_ty.zigTypeTag()) {
4793 .Fn => break :func_ty callee_ty,4817 .Fn => break :func_ty callee_ty,
...@@ -4799,7 +4823,7 @@ fn analyzeCall(...@@ -4799,7 +4823,7 @@ fn analyzeCall(
4799 },4823 },
4800 else => {},4824 else => {},
4801 }4825 }
4802 return sema.fail(block, func_src, "type '{}' not a function", .{callee_ty.fmt(target)});4826 return sema.fail(block, func_src, "type '{}' not a function", .{callee_ty.fmt(sema.mod)});
4803 };4827 };
48044828
4805 const func_ty_info = func_ty.fnInfo();4829 const func_ty_info = func_ty.fnInfo();
...@@ -4891,7 +4915,7 @@ fn analyzeCall(...@@ -4891,7 +4915,7 @@ fn analyzeCall(
4891 const result: Air.Inst.Ref = if (is_inline_call) res: {4915 const result: Air.Inst.Ref = if (is_inline_call) res: {
4892 const func_val = try sema.resolveConstValue(block, func_src, func);4916 const func_val = try sema.resolveConstValue(block, func_src, func);
4893 const module_fn = switch (func_val.tag()) {4917 const module_fn = switch (func_val.tag()) {
4894 .decl_ref => func_val.castTag(.decl_ref).?.data.val.castTag(.function).?.data,4918 .decl_ref => mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data,
4895 .function => func_val.castTag(.function).?.data,4919 .function => func_val.castTag(.function).?.data,
4896 .extern_fn => return sema.fail(block, call_src, "{s} call of extern function", .{4920 .extern_fn => return sema.fail(block, call_src, "{s} call of extern function", .{
4897 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),4921 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),
...@@ -4922,7 +4946,8 @@ fn analyzeCall(...@@ -4922,7 +4946,8 @@ fn analyzeCall(
4922 // In order to save a bit of stack space, directly modify Sema rather4946 // In order to save a bit of stack space, directly modify Sema rather
4923 // than create a child one.4947 // than create a child one.
4924 const parent_zir = sema.code;4948 const parent_zir = sema.code;
4925 sema.code = module_fn.owner_decl.getFileScope().zir;4949 const fn_owner_decl = mod.declPtr(module_fn.owner_decl);
4950 sema.code = fn_owner_decl.getFileScope().zir;
4926 defer sema.code = parent_zir;4951 defer sema.code = parent_zir;
49274952
4928 const parent_inst_map = sema.inst_map;4953 const parent_inst_map = sema.inst_map;
...@@ -4936,14 +4961,14 @@ fn analyzeCall(...@@ -4936,14 +4961,14 @@ fn analyzeCall(
4936 sema.func = module_fn;4961 sema.func = module_fn;
4937 defer sema.func = parent_func;4962 defer sema.func = parent_func;
49384963
4939 var wip_captures = try WipCaptureScope.init(gpa, sema.perm_arena, module_fn.owner_decl.src_scope);4964 var wip_captures = try WipCaptureScope.init(gpa, sema.perm_arena, fn_owner_decl.src_scope);
4940 defer wip_captures.deinit();4965 defer wip_captures.deinit();
49414966
4942 var child_block: Block = .{4967 var child_block: Block = .{
4943 .parent = null,4968 .parent = null,
4944 .sema = sema,4969 .sema = sema,
4945 .src_decl = module_fn.owner_decl,4970 .src_decl = module_fn.owner_decl,
4946 .namespace = module_fn.owner_decl.src_namespace,4971 .namespace = fn_owner_decl.src_namespace,
4947 .wip_capture_scope = wip_captures.scope,4972 .wip_capture_scope = wip_captures.scope,
4948 .instructions = .{},4973 .instructions = .{},
4949 .label = null,4974 .label = null,
...@@ -4976,7 +5001,7 @@ fn analyzeCall(...@@ -4976,7 +5001,7 @@ fn analyzeCall(
4976 // comptime state.5001 // comptime state.
4977 var should_memoize = true;5002 var should_memoize = true;
49785003
4979 var new_fn_info = module_fn.owner_decl.ty.fnInfo();5004 var new_fn_info = fn_owner_decl.ty.fnInfo();
4980 new_fn_info.param_types = try sema.arena.alloc(Type, new_fn_info.param_types.len);5005 new_fn_info.param_types = try sema.arena.alloc(Type, new_fn_info.param_types.len);
4981 new_fn_info.comptime_params = (try sema.arena.alloc(bool, new_fn_info.param_types.len)).ptr;5006 new_fn_info.comptime_params = (try sema.arena.alloc(bool, new_fn_info.param_types.len)).ptr;
49825007
...@@ -5073,7 +5098,7 @@ fn analyzeCall(...@@ -5073,7 +5098,7 @@ fn analyzeCall(
5073 const bare_return_type = try sema.analyzeAsType(&child_block, ret_ty_src, ret_ty_inst);5098 const bare_return_type = try sema.analyzeAsType(&child_block, ret_ty_src, ret_ty_inst);
5074 // Create a fresh inferred error set type for inline/comptime calls.5099 // Create a fresh inferred error set type for inline/comptime calls.
5075 const fn_ret_ty = blk: {5100 const fn_ret_ty = blk: {
5076 if (module_fn.hasInferredErrorSet()) {5101 if (module_fn.hasInferredErrorSet(mod)) {
5077 const node = try sema.gpa.create(Module.Fn.InferredErrorSetListNode);5102 const node = try sema.gpa.create(Module.Fn.InferredErrorSetListNode);
5078 node.data = .{ .func = module_fn };5103 node.data = .{ .func = module_fn };
5079 if (parent_func) |some| {5104 if (parent_func) |some| {
...@@ -5097,7 +5122,7 @@ fn analyzeCall(...@@ -5097,7 +5122,7 @@ fn analyzeCall(
5097 // bug generating invalid LLVM IR.5122 // bug generating invalid LLVM IR.
5098 const res2: Air.Inst.Ref = res2: {5123 const res2: Air.Inst.Ref = res2: {
5099 if (should_memoize and is_comptime_call) {5124 if (should_memoize and is_comptime_call) {
5100 if (mod.memoized_calls.getContext(memoized_call_key, .{ .target = target })) |result| {5125 if (mod.memoized_calls.getContext(memoized_call_key, .{ .module = mod })) |result| {
5101 const ty_inst = try sema.addType(fn_ret_ty);5126 const ty_inst = try sema.addType(fn_ret_ty);
5102 try sema.air_values.append(gpa, result.val);5127 try sema.air_values.append(gpa, result.val);
5103 sema.air_instructions.set(block_inst, .{5128 sema.air_instructions.set(block_inst, .{
...@@ -5150,7 +5175,13 @@ fn analyzeCall(...@@ -5150,7 +5175,13 @@ fn analyzeCall(
5150 };5175 };
51515176
5152 if (!is_comptime_call) {5177 if (!is_comptime_call) {
5153 try sema.emitDbgInline(block, module_fn, parent_func.?, parent_func.?.owner_decl.ty, .dbg_inline_end);5178 try sema.emitDbgInline(
5179 block,
5180 module_fn,
5181 parent_func.?,
5182 mod.declPtr(parent_func.?.owner_decl).ty,
5183 .dbg_inline_end,
5184 );
5154 }5185 }
51555186
5156 if (should_memoize and is_comptime_call) {5187 if (should_memoize and is_comptime_call) {
...@@ -5172,7 +5203,7 @@ fn analyzeCall(...@@ -5172,7 +5203,7 @@ fn analyzeCall(
5172 try mod.memoized_calls.putContext(gpa, memoized_call_key, .{5203 try mod.memoized_calls.putContext(gpa, memoized_call_key, .{
5173 .val = try result_val.copy(arena),5204 .val = try result_val.copy(arena),
5174 .arena = arena_allocator.state,5205 .arena = arena_allocator.state,
5175 }, .{ .target = sema.mod.getTarget() });5206 }, .{ .module = mod });
5176 delete_memoized_call_key = false;5207 delete_memoized_call_key = false;
5177 }5208 }
5178 }5209 }
...@@ -5239,13 +5270,14 @@ fn instantiateGenericCall(...@@ -5239,13 +5270,14 @@ fn instantiateGenericCall(
5239 const func_val = try sema.resolveConstValue(block, func_src, func);5270 const func_val = try sema.resolveConstValue(block, func_src, func);
5240 const module_fn = switch (func_val.tag()) {5271 const module_fn = switch (func_val.tag()) {
5241 .function => func_val.castTag(.function).?.data,5272 .function => func_val.castTag(.function).?.data,
5242 .decl_ref => func_val.castTag(.decl_ref).?.data.val.castTag(.function).?.data,5273 .decl_ref => mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data,
5243 else => unreachable,5274 else => unreachable,
5244 };5275 };
5245 // Check the Module's generic function map with an adapted context, so that we5276 // Check the Module's generic function map with an adapted context, so that we
5246 // can match against `uncasted_args` rather than doing the work below to create a5277 // can match against `uncasted_args` rather than doing the work below to create a
5247 // generic Scope only to junk it if it matches an existing instantiation.5278 // generic Scope only to junk it if it matches an existing instantiation.
5248 const namespace = module_fn.owner_decl.src_namespace;5279 const fn_owner_decl = mod.declPtr(module_fn.owner_decl);
5280 const namespace = fn_owner_decl.src_namespace;
5249 const fn_zir = namespace.file_scope.zir;5281 const fn_zir = namespace.file_scope.zir;
5250 const fn_info = fn_zir.getFnInfo(module_fn.zir_body_inst);5282 const fn_info = fn_zir.getFnInfo(module_fn.zir_body_inst);
5251 const zir_tags = fn_zir.instructions.items(.tag);5283 const zir_tags = fn_zir.instructions.items(.tag);
...@@ -5261,7 +5293,6 @@ fn instantiateGenericCall(...@@ -5261,7 +5293,6 @@ fn instantiateGenericCall(
5261 std.hash.autoHash(&hasher, @ptrToInt(module_fn));5293 std.hash.autoHash(&hasher, @ptrToInt(module_fn));
52625294
5263 const comptime_tvs = try sema.arena.alloc(TypedValue, func_ty_info.param_types.len);5295 const comptime_tvs = try sema.arena.alloc(TypedValue, func_ty_info.param_types.len);
5264 const target = sema.mod.getTarget();
52655296
5266 {5297 {
5267 var i: usize = 0;5298 var i: usize = 0;
...@@ -5290,9 +5321,9 @@ fn instantiateGenericCall(...@@ -5290,9 +5321,9 @@ fn instantiateGenericCall(
5290 const arg_src = call_src; // TODO better source location5321 const arg_src = call_src; // TODO better source location
5291 const arg_ty = sema.typeOf(uncasted_args[i]);5322 const arg_ty = sema.typeOf(uncasted_args[i]);
5292 const arg_val = try sema.resolveValue(block, arg_src, uncasted_args[i]);5323 const arg_val = try sema.resolveValue(block, arg_src, uncasted_args[i]);
5293 arg_val.hash(arg_ty, &hasher, target);5324 arg_val.hash(arg_ty, &hasher, mod);
5294 if (is_anytype) {5325 if (is_anytype) {
5295 arg_ty.hashWithHasher(&hasher, target);5326 arg_ty.hashWithHasher(&hasher, mod);
5296 comptime_tvs[i] = .{5327 comptime_tvs[i] = .{
5297 .ty = arg_ty,5328 .ty = arg_ty,
5298 .val = arg_val,5329 .val = arg_val,
...@@ -5305,7 +5336,7 @@ fn instantiateGenericCall(...@@ -5305,7 +5336,7 @@ fn instantiateGenericCall(
5305 }5336 }
5306 } else if (is_anytype) {5337 } else if (is_anytype) {
5307 const arg_ty = sema.typeOf(uncasted_args[i]);5338 const arg_ty = sema.typeOf(uncasted_args[i]);
5308 arg_ty.hashWithHasher(&hasher, target);5339 arg_ty.hashWithHasher(&hasher, mod);
5309 comptime_tvs[i] = .{5340 comptime_tvs[i] = .{
5310 .ty = arg_ty,5341 .ty = arg_ty,
5311 .val = Value.initTag(.generic_poison),5342 .val = Value.initTag(.generic_poison),
...@@ -5328,7 +5359,7 @@ fn instantiateGenericCall(...@@ -5328,7 +5359,7 @@ fn instantiateGenericCall(
5328 .precomputed_hash = precomputed_hash,5359 .precomputed_hash = precomputed_hash,
5329 .func_ty_info = func_ty_info,5360 .func_ty_info = func_ty_info,
5330 .comptime_tvs = comptime_tvs,5361 .comptime_tvs = comptime_tvs,
5331 .target = target,5362 .module = mod,
5332 };5363 };
5333 const gop = try mod.monomorphed_funcs.getOrPutAdapted(gpa, {}, adapter);5364 const gop = try mod.monomorphed_funcs.getOrPutAdapted(gpa, {}, adapter);
5334 const callee = if (!gop.found_existing) callee: {5365 const callee = if (!gop.found_existing) callee: {
...@@ -5343,37 +5374,40 @@ fn instantiateGenericCall(...@@ -5343,37 +5374,40 @@ fn instantiateGenericCall(
5343 try namespace.anon_decls.ensureUnusedCapacity(gpa, 1);5374 try namespace.anon_decls.ensureUnusedCapacity(gpa, 1);
53445375
5345 // Create a Decl for the new function.5376 // Create a Decl for the new function.
5346 const src_decl = namespace.getDecl();5377 const src_decl_index = namespace.getDeclIndex();
5378 const src_decl = mod.declPtr(src_decl_index);
5379 const new_decl_index = try mod.allocateNewDecl(namespace, fn_owner_decl.src_node, src_decl.src_scope);
5380 errdefer mod.destroyDecl(new_decl_index);
5381 const new_decl = mod.declPtr(new_decl_index);
5347 // TODO better names for generic function instantiations5382 // TODO better names for generic function instantiations
5348 const name_index = mod.getNextAnonNameIndex();
5349 const decl_name = try std.fmt.allocPrintZ(gpa, "{s}__anon_{d}", .{5383 const decl_name = try std.fmt.allocPrintZ(gpa, "{s}__anon_{d}", .{
5350 module_fn.owner_decl.name, name_index,5384 fn_owner_decl.name, @enumToInt(new_decl_index),
5351 });5385 });
5352 const new_decl = try mod.allocateNewDecl(decl_name, namespace, module_fn.owner_decl.src_node, src_decl.src_scope);5386 new_decl.name = decl_name;
5353 errdefer new_decl.destroy(mod);5387 new_decl.src_line = fn_owner_decl.src_line;
5354 new_decl.src_line = module_fn.owner_decl.src_line;5388 new_decl.is_pub = fn_owner_decl.is_pub;
5355 new_decl.is_pub = module_fn.owner_decl.is_pub;5389 new_decl.is_exported = fn_owner_decl.is_exported;
5356 new_decl.is_exported = module_fn.owner_decl.is_exported;5390 new_decl.has_align = fn_owner_decl.has_align;
5357 new_decl.has_align = module_fn.owner_decl.has_align;5391 new_decl.has_linksection_or_addrspace = fn_owner_decl.has_linksection_or_addrspace;
5358 new_decl.has_linksection_or_addrspace = module_fn.owner_decl.has_linksection_or_addrspace;5392 new_decl.@"addrspace" = fn_owner_decl.@"addrspace";
5359 new_decl.@"addrspace" = module_fn.owner_decl.@"addrspace";5393 new_decl.zir_decl_index = fn_owner_decl.zir_decl_index;
5360 new_decl.zir_decl_index = module_fn.owner_decl.zir_decl_index;
5361 new_decl.alive = true; // This Decl is called at runtime.5394 new_decl.alive = true; // This Decl is called at runtime.
5362 new_decl.analysis = .in_progress;5395 new_decl.analysis = .in_progress;
5363 new_decl.generation = mod.generation;5396 new_decl.generation = mod.generation;
53645397
5365 namespace.anon_decls.putAssumeCapacityNoClobber(new_decl, {});5398 namespace.anon_decls.putAssumeCapacityNoClobber(new_decl_index, {});
5366 errdefer assert(namespace.anon_decls.orderedRemove(new_decl));5399 errdefer assert(namespace.anon_decls.orderedRemove(new_decl_index));
53675400
5368 // The generic function Decl is guaranteed to be the first dependency5401 // The generic function Decl is guaranteed to be the first dependency
5369 // of each of its instantiations.5402 // of each of its instantiations.
5370 assert(new_decl.dependencies.keys().len == 0);5403 assert(new_decl.dependencies.keys().len == 0);
5371 try mod.declareDeclDependency(new_decl, module_fn.owner_decl);5404 try mod.declareDeclDependency(new_decl_index, module_fn.owner_decl);
5372 // Resolving the new function type below will possibly declare more decl dependencies5405 // Resolving the new function type below will possibly declare more decl dependencies
5373 // and so we remove them all here in case of error.5406 // and so we remove them all here in case of error.
5374 errdefer {5407 errdefer {
5375 for (new_decl.dependencies.keys()) |dep| {5408 for (new_decl.dependencies.keys()) |dep_index| {
5376 dep.removeDependant(new_decl);5409 const dep = mod.declPtr(dep_index);
5410 dep.removeDependant(new_decl_index);
5377 }5411 }
5378 }5412 }
53795413
...@@ -5392,6 +5426,7 @@ fn instantiateGenericCall(...@@ -5392,6 +5426,7 @@ fn instantiateGenericCall(
5392 .perm_arena = new_decl_arena_allocator,5426 .perm_arena = new_decl_arena_allocator,
5393 .code = fn_zir,5427 .code = fn_zir,
5394 .owner_decl = new_decl,5428 .owner_decl = new_decl,
5429 .owner_decl_index = new_decl_index,
5395 .func = null,5430 .func = null,
5396 .fn_ret_ty = Type.void,5431 .fn_ret_ty = Type.void,
5397 .owner_func = null,5432 .owner_func = null,
...@@ -5407,7 +5442,7 @@ fn instantiateGenericCall(...@@ -5407,7 +5442,7 @@ fn instantiateGenericCall(
5407 var child_block: Block = .{5442 var child_block: Block = .{
5408 .parent = null,5443 .parent = null,
5409 .sema = &child_sema,5444 .sema = &child_sema,
5410 .src_decl = new_decl,5445 .src_decl = new_decl_index,
5411 .namespace = namespace,5446 .namespace = namespace,
5412 .wip_capture_scope = wip_captures.scope,5447 .wip_capture_scope = wip_captures.scope,
5413 .instructions = .{},5448 .instructions = .{},
...@@ -5564,7 +5599,7 @@ fn instantiateGenericCall(...@@ -5564,7 +5599,7 @@ fn instantiateGenericCall(
5564 // Queue up a `codegen_func` work item for the new Fn. The `comptime_args` field5599 // Queue up a `codegen_func` work item for the new Fn. The `comptime_args` field
5565 // will be populated, ensuring it will have `analyzeBody` called with the ZIR5600 // will be populated, ensuring it will have `analyzeBody` called with the ZIR
5566 // parameters mapped appropriately.5601 // parameters mapped appropriately.
5567 try mod.comp.bin_file.allocateDeclIndexes(new_decl);5602 try mod.comp.bin_file.allocateDeclIndexes(new_decl_index);
5568 try mod.comp.work_queue.writeItem(.{ .codegen_func = new_func });5603 try mod.comp.work_queue.writeItem(.{ .codegen_func = new_func });
55695604
5570 try new_decl.finalizeNewArena(&new_decl_arena);5605 try new_decl.finalizeNewArena(&new_decl_arena);
...@@ -5577,7 +5612,7 @@ fn instantiateGenericCall(...@@ -5577,7 +5612,7 @@ fn instantiateGenericCall(
5577 try sema.requireRuntimeBlock(block, call_src);5612 try sema.requireRuntimeBlock(block, call_src);
55785613
5579 const comptime_args = callee.comptime_args.?;5614 const comptime_args = callee.comptime_args.?;
5580 const new_fn_info = callee.owner_decl.ty.fnInfo();5615 const new_fn_info = mod.declPtr(callee.owner_decl).ty.fnInfo();
5581 const runtime_args_len = @intCast(u32, new_fn_info.param_types.len);5616 const runtime_args_len = @intCast(u32, new_fn_info.param_types.len);
5582 const runtime_args = try sema.arena.alloc(Air.Inst.Ref, runtime_args_len);5617 const runtime_args = try sema.arena.alloc(Air.Inst.Ref, runtime_args_len);
5583 {5618 {
...@@ -5700,8 +5735,7 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -5700,8 +5735,7 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
5700 const bin_inst = sema.code.instructions.items(.data)[inst].bin;5735 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
5701 const len = try sema.resolveInt(block, .unneeded, bin_inst.lhs, Type.usize);5736 const len = try sema.resolveInt(block, .unneeded, bin_inst.lhs, Type.usize);
5702 const elem_type = try sema.resolveType(block, .unneeded, bin_inst.rhs);5737 const elem_type = try sema.resolveType(block, .unneeded, bin_inst.rhs);
5703 const target = sema.mod.getTarget();5738 const array_ty = try Type.array(sema.arena, len, null, elem_type, sema.mod);
5704 const array_ty = try Type.array(sema.arena, len, null, elem_type, target);
57055739
5706 return sema.addType(array_ty);5740 return sema.addType(array_ty);
5707}5741}
...@@ -5720,8 +5754,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -5720,8 +5754,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
5720 const uncasted_sentinel = sema.resolveInst(extra.sentinel);5754 const uncasted_sentinel = sema.resolveInst(extra.sentinel);
5721 const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src);5755 const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src);
5722 const sentinel_val = try sema.resolveConstValue(block, sentinel_src, sentinel);5756 const sentinel_val = try sema.resolveConstValue(block, sentinel_src, sentinel);
5723 const target = sema.mod.getTarget();5757 const array_ty = try Type.array(sema.arena, len, sentinel_val, elem_type, sema.mod);
5724 const array_ty = try Type.array(sema.arena, len, sentinel_val, elem_type, target);
57255758
5726 return sema.addType(array_ty);5759 return sema.addType(array_ty);
5727}5760}
...@@ -5748,14 +5781,13 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -5748,14 +5781,13 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
5748 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };5781 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
5749 const error_set = try sema.resolveType(block, lhs_src, extra.lhs);5782 const error_set = try sema.resolveType(block, lhs_src, extra.lhs);
5750 const payload = try sema.resolveType(block, rhs_src, extra.rhs);5783 const payload = try sema.resolveType(block, rhs_src, extra.rhs);
5751 const target = sema.mod.getTarget();
57525784
5753 if (error_set.zigTypeTag() != .ErrorSet) {5785 if (error_set.zigTypeTag() != .ErrorSet) {
5754 return sema.fail(block, lhs_src, "expected error set type, found {}", .{5786 return sema.fail(block, lhs_src, "expected error set type, found {}", .{
5755 error_set.fmt(target),5787 error_set.fmt(sema.mod),
5756 });5788 });
5757 }5789 }
5758 const err_union_ty = try Type.errorUnion(sema.arena, error_set, payload, target);5790 const err_union_ty = try Type.errorUnion(sema.arena, error_set, payload, sema.mod);
5759 return sema.addType(err_union_ty);5791 return sema.addType(err_union_ty);
5760}5792}
57615793
...@@ -5862,11 +5894,10 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -5862,11 +5894,10 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
5862 }5894 }
5863 const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs);5895 const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs);
5864 const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs);5896 const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs);
5865 const target = sema.mod.getTarget();
5866 if (lhs_ty.zigTypeTag() != .ErrorSet)5897 if (lhs_ty.zigTypeTag() != .ErrorSet)
5867 return sema.fail(block, lhs_src, "expected error set type, found {}", .{lhs_ty.fmt(target)});5898 return sema.fail(block, lhs_src, "expected error set type, found {}", .{lhs_ty.fmt(sema.mod)});
5868 if (rhs_ty.zigTypeTag() != .ErrorSet)5899 if (rhs_ty.zigTypeTag() != .ErrorSet)
5869 return sema.fail(block, rhs_src, "expected error set type, found {}", .{rhs_ty.fmt(target)});5900 return sema.fail(block, rhs_src, "expected error set type, found {}", .{rhs_ty.fmt(sema.mod)});
58705901
5871 // Anything merged with anyerror is anyerror.5902 // Anything merged with anyerror is anyerror.
5872 if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror) {5903 if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror) {
...@@ -5912,7 +5943,6 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -5912,7 +5943,6 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
5912 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };5943 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
5913 const operand = sema.resolveInst(inst_data.operand);5944 const operand = sema.resolveInst(inst_data.operand);
5914 const operand_ty = sema.typeOf(operand);5945 const operand_ty = sema.typeOf(operand);
5915 const target = sema.mod.getTarget();
59165946
5917 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag()) {5947 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag()) {
5918 .Enum => operand,5948 .Enum => operand,
...@@ -5929,7 +5959,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -5929,7 +5959,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
5929 },5959 },
5930 else => {5960 else => {
5931 return sema.fail(block, operand_src, "expected enum or tagged union, found {}", .{5961 return sema.fail(block, operand_src, "expected enum or tagged union, found {}", .{
5932 operand_ty.fmt(target),5962 operand_ty.fmt(sema.mod),
5933 });5963 });
5934 },5964 },
5935 };5965 };
...@@ -5953,7 +5983,6 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -5953,7 +5983,6 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
5953}5983}
59545984
5955fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5985fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
5956 const target = sema.mod.getTarget();
5957 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;5986 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
5958 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;5987 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
5959 const src = inst_data.src();5988 const src = inst_data.src();
...@@ -5963,7 +5992,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -5963,7 +5992,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
5963 const operand = sema.resolveInst(extra.rhs);5992 const operand = sema.resolveInst(extra.rhs);
59645993
5965 if (dest_ty.zigTypeTag() != .Enum) {5994 if (dest_ty.zigTypeTag() != .Enum) {
5966 return sema.fail(block, dest_ty_src, "expected enum, found {}", .{dest_ty.fmt(target)});5995 return sema.fail(block, dest_ty_src, "expected enum, found {}", .{dest_ty.fmt(sema.mod)});
5967 }5996 }
59685997
5969 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |int_val| {5998 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |int_val| {
...@@ -5973,17 +6002,17 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -5973,17 +6002,17 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
5973 if (int_val.isUndef()) {6002 if (int_val.isUndef()) {
5974 return sema.failWithUseOfUndef(block, operand_src);6003 return sema.failWithUseOfUndef(block, operand_src);
5975 }6004 }
5976 if (!dest_ty.enumHasInt(int_val, target)) {6005 if (!dest_ty.enumHasInt(int_val, sema.mod)) {
5977 const msg = msg: {6006 const msg = msg: {
5978 const msg = try sema.errMsg(6007 const msg = try sema.errMsg(
5979 block,6008 block,
5980 src,6009 src,
5981 "enum '{}' has no tag with value {}",6010 "enum '{}' has no tag with value {}",
5982 .{ dest_ty.fmt(target), int_val.fmtValue(sema.typeOf(operand), target) },6011 .{ dest_ty.fmt(sema.mod), int_val.fmtValue(sema.typeOf(operand), sema.mod) },
5983 );6012 );
5984 errdefer msg.destroy(sema.gpa);6013 errdefer msg.destroy(sema.gpa);
5985 try sema.mod.errNoteNonLazy(6014 try sema.mod.errNoteNonLazy(
5986 dest_ty.declSrcLoc(),6015 dest_ty.declSrcLoc(sema.mod),
5987 msg,6016 msg,
5988 "enum declared here",6017 "enum declared here",
5989 .{},6018 .{},
...@@ -6028,14 +6057,13 @@ fn analyzeOptionalPayloadPtr(...@@ -6028,14 +6057,13 @@ fn analyzeOptionalPayloadPtr(
6028 const optional_ptr_ty = sema.typeOf(optional_ptr);6057 const optional_ptr_ty = sema.typeOf(optional_ptr);
6029 assert(optional_ptr_ty.zigTypeTag() == .Pointer);6058 assert(optional_ptr_ty.zigTypeTag() == .Pointer);
60306059
6031 const target = sema.mod.getTarget();
6032 const opt_type = optional_ptr_ty.elemType();6060 const opt_type = optional_ptr_ty.elemType();
6033 if (opt_type.zigTypeTag() != .Optional) {6061 if (opt_type.zigTypeTag() != .Optional) {
6034 return sema.fail(block, src, "expected optional type, found {}", .{opt_type.fmt(target)});6062 return sema.fail(block, src, "expected optional type, found {}", .{opt_type.fmt(sema.mod)});
6035 }6063 }
60366064
6037 const child_type = try opt_type.optionalChildAlloc(sema.arena);6065 const child_type = try opt_type.optionalChildAlloc(sema.arena);
6038 const child_pointer = try Type.ptr(sema.arena, target, .{6066 const child_pointer = try Type.ptr(sema.arena, sema.mod, .{
6039 .pointee_type = child_type,6067 .pointee_type = child_type,
6040 .mutable = !optional_ptr_ty.isConstPtr(),6068 .mutable = !optional_ptr_ty.isConstPtr(),
6041 .@"addrspace" = optional_ptr_ty.ptrAddressSpace(),6069 .@"addrspace" = optional_ptr_ty.ptrAddressSpace(),
...@@ -6106,8 +6134,7 @@ fn zirOptionalPayload(...@@ -6106,8 +6134,7 @@ fn zirOptionalPayload(
6106 return sema.failWithExpectedOptionalType(block, src, operand_ty);6134 return sema.failWithExpectedOptionalType(block, src, operand_ty);
6107 }6135 }
6108 const ptr_info = operand_ty.ptrInfo().data;6136 const ptr_info = operand_ty.ptrInfo().data;
6109 const target = sema.mod.getTarget();6137 break :t try Type.ptr(sema.arena, sema.mod, .{
6110 break :t try Type.ptr(sema.arena, target, .{
6111 .pointee_type = try ptr_info.pointee_type.copy(sema.arena),6138 .pointee_type = try ptr_info.pointee_type.copy(sema.arena),
6112 .@"align" = ptr_info.@"align",6139 .@"align" = ptr_info.@"align",
6113 .@"addrspace" = ptr_info.@"addrspace",6140 .@"addrspace" = ptr_info.@"addrspace",
...@@ -6154,9 +6181,8 @@ fn zirErrUnionPayload(...@@ -6154,9 +6181,8 @@ fn zirErrUnionPayload(
6154 const operand_src = src;6181 const operand_src = src;
6155 const operand_ty = sema.typeOf(operand);6182 const operand_ty = sema.typeOf(operand);
6156 if (operand_ty.zigTypeTag() != .ErrorUnion) {6183 if (operand_ty.zigTypeTag() != .ErrorUnion) {
6157 const target = sema.mod.getTarget();
6158 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{6184 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{
6159 operand_ty.fmt(target),6185 operand_ty.fmt(sema.mod),
6160 });6186 });
6161 }6187 }
61626188
...@@ -6205,15 +6231,14 @@ fn analyzeErrUnionPayloadPtr(...@@ -6205,15 +6231,14 @@ fn analyzeErrUnionPayloadPtr(
6205 const operand_ty = sema.typeOf(operand);6231 const operand_ty = sema.typeOf(operand);
6206 assert(operand_ty.zigTypeTag() == .Pointer);6232 assert(operand_ty.zigTypeTag() == .Pointer);
62076233
6208 const target = sema.mod.getTarget();
6209 if (operand_ty.elemType().zigTypeTag() != .ErrorUnion) {6234 if (operand_ty.elemType().zigTypeTag() != .ErrorUnion) {
6210 return sema.fail(block, src, "expected error union type, found {}", .{6235 return sema.fail(block, src, "expected error union type, found {}", .{
6211 operand_ty.elemType().fmt(target),6236 operand_ty.elemType().fmt(sema.mod),
6212 });6237 });
6213 }6238 }
62146239
6215 const payload_ty = operand_ty.elemType().errorUnionPayload();6240 const payload_ty = operand_ty.elemType().errorUnionPayload();
6216 const operand_pointer_ty = try Type.ptr(sema.arena, target, .{6241 const operand_pointer_ty = try Type.ptr(sema.arena, sema.mod, .{
6217 .pointee_type = payload_ty,6242 .pointee_type = payload_ty,
6218 .mutable = !operand_ty.isConstPtr(),6243 .mutable = !operand_ty.isConstPtr(),
6219 .@"addrspace" = operand_ty.ptrAddressSpace(),6244 .@"addrspace" = operand_ty.ptrAddressSpace(),
...@@ -6272,10 +6297,9 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -6272,10 +6297,9 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
6272 const src = inst_data.src();6297 const src = inst_data.src();
6273 const operand = sema.resolveInst(inst_data.operand);6298 const operand = sema.resolveInst(inst_data.operand);
6274 const operand_ty = sema.typeOf(operand);6299 const operand_ty = sema.typeOf(operand);
6275 const target = sema.mod.getTarget();
6276 if (operand_ty.zigTypeTag() != .ErrorUnion) {6300 if (operand_ty.zigTypeTag() != .ErrorUnion) {
6277 return sema.fail(block, src, "expected error union type, found '{}'", .{6301 return sema.fail(block, src, "expected error union type, found '{}'", .{
6278 operand_ty.fmt(target),6302 operand_ty.fmt(sema.mod),
6279 });6303 });
6280 }6304 }
62816305
...@@ -6302,9 +6326,8 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -6302,9 +6326,8 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
6302 assert(operand_ty.zigTypeTag() == .Pointer);6326 assert(operand_ty.zigTypeTag() == .Pointer);
63036327
6304 if (operand_ty.elemType().zigTypeTag() != .ErrorUnion) {6328 if (operand_ty.elemType().zigTypeTag() != .ErrorUnion) {
6305 const target = sema.mod.getTarget();
6306 return sema.fail(block, src, "expected error union type, found {}", .{6329 return sema.fail(block, src, "expected error union type, found {}", .{
6307 operand_ty.elemType().fmt(target),6330 operand_ty.elemType().fmt(sema.mod),
6308 });6331 });
6309 }6332 }
63106333
...@@ -6329,10 +6352,9 @@ fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -6329,10 +6352,9 @@ fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
6329 const src = inst_data.src();6352 const src = inst_data.src();
6330 const operand = sema.resolveInst(inst_data.operand);6353 const operand = sema.resolveInst(inst_data.operand);
6331 const operand_ty = sema.typeOf(operand);6354 const operand_ty = sema.typeOf(operand);
6332 const target = sema.mod.getTarget();
6333 if (operand_ty.zigTypeTag() != .ErrorUnion) {6355 if (operand_ty.zigTypeTag() != .ErrorUnion) {
6334 return sema.fail(block, src, "expected error union type, found '{}'", .{6356 return sema.fail(block, src, "expected error union type, found '{}'", .{
6335 operand_ty.fmt(target),6357 operand_ty.fmt(sema.mod),
6336 });6358 });
6337 }6359 }
6338 if (operand_ty.errorUnionPayload().zigTypeTag() != .Void) {6360 if (operand_ty.errorUnionPayload().zigTypeTag() != .Void) {
...@@ -6606,7 +6628,7 @@ fn funcCommon(...@@ -6606,7 +6628,7 @@ fn funcCommon(
6606 errdefer sema.gpa.destroy(new_extern_fn);6628 errdefer sema.gpa.destroy(new_extern_fn);
66076629
6608 new_extern_fn.* = Module.ExternFn{6630 new_extern_fn.* = Module.ExternFn{
6609 .owner_decl = sema.owner_decl,6631 .owner_decl = sema.owner_decl_index,
6610 .lib_name = null,6632 .lib_name = null,
6611 };6633 };
66126634
...@@ -6645,7 +6667,7 @@ fn funcCommon(...@@ -6645,7 +6667,7 @@ fn funcCommon(
6645 new_func.* = .{6667 new_func.* = .{
6646 .state = anal_state,6668 .state = anal_state,
6647 .zir_body_inst = func_inst,6669 .zir_body_inst = func_inst,
6648 .owner_decl = sema.owner_decl,6670 .owner_decl = sema.owner_decl_index,
6649 .comptime_args = comptime_args,6671 .comptime_args = comptime_args,
6650 .anytype_args = undefined,6672 .anytype_args = undefined,
6651 .hash = hash,6673 .hash = hash,
...@@ -6838,8 +6860,7 @@ fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -6838,8 +6860,7 @@ fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
6838 const ptr = sema.resolveInst(inst_data.operand);6860 const ptr = sema.resolveInst(inst_data.operand);
6839 const ptr_ty = sema.typeOf(ptr);6861 const ptr_ty = sema.typeOf(ptr);
6840 if (!ptr_ty.isPtrAtRuntime()) {6862 if (!ptr_ty.isPtrAtRuntime()) {
6841 const target = sema.mod.getTarget();6863 return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(sema.mod)});
6842 return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(target)});
6843 }6864 }
6844 if (try sema.resolveMaybeUndefVal(block, ptr_src, ptr)) |ptr_val| {6865 if (try sema.resolveMaybeUndefVal(block, ptr_src, ptr)) |ptr_val| {
6845 return sema.addConstant(Type.usize, ptr_val);6866 return sema.addConstant(Type.usize, ptr_val);
...@@ -7018,7 +7039,6 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -7018,7 +7039,6 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
7018 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };7039 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
7019 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };7040 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
7020 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;7041 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
7021 const target = sema.mod.getTarget();
70227042
7023 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);7043 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
7024 switch (dest_ty.zigTypeTag()) {7044 switch (dest_ty.zigTypeTag()) {
...@@ -7038,10 +7058,10 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -7038,10 +7058,10 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
7038 .Type,7058 .Type,
7039 .Undefined,7059 .Undefined,
7040 .Void,7060 .Void,
7041 => return sema.fail(block, dest_ty_src, "invalid type '{}' for @bitCast", .{dest_ty.fmt(target)}),7061 => return sema.fail(block, dest_ty_src, "invalid type '{}' for @bitCast", .{dest_ty.fmt(sema.mod)}),
70427062
7043 .Pointer => return sema.fail(block, dest_ty_src, "cannot @bitCast to '{}', use @ptrCast to cast to a pointer", .{7063 .Pointer => return sema.fail(block, dest_ty_src, "cannot @bitCast to '{}', use @ptrCast to cast to a pointer", .{
7044 dest_ty.fmt(target),7064 dest_ty.fmt(sema.mod),
7045 }),7065 }),
7046 .Struct, .Union => if (dest_ty.containerLayout() == .Auto) {7066 .Struct, .Union => if (dest_ty.containerLayout() == .Auto) {
7047 const container = switch (dest_ty.zigTypeTag()) {7067 const container = switch (dest_ty.zigTypeTag()) {
...@@ -7050,7 +7070,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -7050,7 +7070,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
7050 else => unreachable,7070 else => unreachable,
7051 };7071 };
7052 return sema.fail(block, dest_ty_src, "cannot @bitCast to '{}', {s} does not have a guaranteed in-memory layout", .{7072 return sema.fail(block, dest_ty_src, "cannot @bitCast to '{}', {s} does not have a guaranteed in-memory layout", .{
7053 dest_ty.fmt(target), container,7073 dest_ty.fmt(sema.mod), container,
7054 });7074 });
7055 },7075 },
7056 .BoundFn => @panic("TODO remove this type from the language and compiler"),7076 .BoundFn => @panic("TODO remove this type from the language and compiler"),
...@@ -7088,7 +7108,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -7088,7 +7108,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
7088 block,7108 block,
7089 dest_ty_src,7109 dest_ty_src,
7090 "expected float type, found '{}'",7110 "expected float type, found '{}'",
7091 .{dest_ty.fmt(target)},7111 .{dest_ty.fmt(sema.mod)},
7092 ),7112 ),
7093 };7113 };
70947114
...@@ -7099,7 +7119,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -7099,7 +7119,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
7099 block,7119 block,
7100 operand_src,7120 operand_src,
7101 "expected float type, found '{}'",7121 "expected float type, found '{}'",
7102 .{operand_ty.fmt(target)},7122 .{operand_ty.fmt(sema.mod)},
7103 ),7123 ),
7104 }7124 }
71057125
...@@ -7241,7 +7261,6 @@ fn zirSwitchCapture(...@@ -7241,7 +7261,6 @@ fn zirSwitchCapture(
7241 const operand_ptr = sema.resolveInst(cond_info.operand);7261 const operand_ptr = sema.resolveInst(cond_info.operand);
7242 const operand_ptr_ty = sema.typeOf(operand_ptr);7262 const operand_ptr_ty = sema.typeOf(operand_ptr);
7243 const operand_ty = if (operand_is_ref) operand_ptr_ty.childType() else operand_ptr_ty;7263 const operand_ty = if (operand_is_ref) operand_ptr_ty.childType() else operand_ptr_ty;
7244 const target = sema.mod.getTarget();
72457264
7246 const operand = if (operand_is_ref)7265 const operand = if (operand_is_ref)
7247 try sema.analyzeLoad(block, operand_src, operand_ptr, operand_src)7266 try sema.analyzeLoad(block, operand_src, operand_ptr, operand_src)
...@@ -7277,7 +7296,7 @@ fn zirSwitchCapture(...@@ -7277,7 +7296,7 @@ fn zirSwitchCapture(
7277 // Previous switch validation ensured this will succeed7296 // Previous switch validation ensured this will succeed
7278 const first_item_val = sema.resolveConstValue(block, .unneeded, first_item) catch unreachable;7297 const first_item_val = sema.resolveConstValue(block, .unneeded, first_item) catch unreachable;
72797298
7280 const first_field_index = @intCast(u32, enum_ty.enumTagFieldIndex(first_item_val, target).?);7299 const first_field_index = @intCast(u32, enum_ty.enumTagFieldIndex(first_item_val, sema.mod).?);
7281 const first_field = union_obj.fields.values()[first_field_index];7300 const first_field = union_obj.fields.values()[first_field_index];
72827301
7283 for (items[1..]) |item| {7302 for (items[1..]) |item| {
...@@ -7285,16 +7304,16 @@ fn zirSwitchCapture(...@@ -7285,16 +7304,16 @@ fn zirSwitchCapture(
7285 // Previous switch validation ensured this will succeed7304 // Previous switch validation ensured this will succeed
7286 const item_val = sema.resolveConstValue(block, .unneeded, item_ref) catch unreachable;7305 const item_val = sema.resolveConstValue(block, .unneeded, item_ref) catch unreachable;
72877306
7288 const field_index = enum_ty.enumTagFieldIndex(item_val, target).?;7307 const field_index = enum_ty.enumTagFieldIndex(item_val, sema.mod).?;
7289 const field = union_obj.fields.values()[field_index];7308 const field = union_obj.fields.values()[field_index];
7290 if (!field.ty.eql(first_field.ty, target)) {7309 if (!field.ty.eql(first_field.ty, sema.mod)) {
7291 const first_item_src = switch_src; // TODO better source location7310 const first_item_src = switch_src; // TODO better source location
7292 const item_src = switch_src;7311 const item_src = switch_src;
7293 const msg = msg: {7312 const msg = msg: {
7294 const msg = try sema.errMsg(block, switch_src, "capture group with incompatible types", .{});7313 const msg = try sema.errMsg(block, switch_src, "capture group with incompatible types", .{});
7295 errdefer msg.destroy(sema.gpa);7314 errdefer msg.destroy(sema.gpa);
7296 try sema.errNote(block, first_item_src, msg, "type '{}' here", .{first_field.ty.fmt(target)});7315 try sema.errNote(block, first_item_src, msg, "type '{}' here", .{first_field.ty.fmt(sema.mod)});
7297 try sema.errNote(block, item_src, msg, "type '{}' here", .{field.ty.fmt(target)});7316 try sema.errNote(block, item_src, msg, "type '{}' here", .{field.ty.fmt(sema.mod)});
7298 break :msg msg;7317 break :msg msg;
7299 };7318 };
7300 return sema.failWithOwnedErrorMsg(block, msg);7319 return sema.failWithOwnedErrorMsg(block, msg);
...@@ -7304,7 +7323,7 @@ fn zirSwitchCapture(...@@ -7304,7 +7323,7 @@ fn zirSwitchCapture(
7304 if (is_ref) {7323 if (is_ref) {
7305 assert(operand_is_ref);7324 assert(operand_is_ref);
73067325
7307 const field_ty_ptr = try Type.ptr(sema.arena, target, .{7326 const field_ty_ptr = try Type.ptr(sema.arena, sema.mod, .{
7308 .pointee_type = first_field.ty,7327 .pointee_type = first_field.ty,
7309 .@"addrspace" = .generic,7328 .@"addrspace" = .generic,
7310 .mutable = operand_ptr_ty.ptrIsMutable(),7329 .mutable = operand_ptr_ty.ptrIsMutable(),
...@@ -7388,7 +7407,6 @@ fn zirSwitchCond(...@@ -7388,7 +7407,6 @@ fn zirSwitchCond(
7388 else7407 else
7389 operand_ptr;7408 operand_ptr;
7390 const operand_ty = sema.typeOf(operand);7409 const operand_ty = sema.typeOf(operand);
7391 const target = sema.mod.getTarget();
73927410
7393 switch (operand_ty.zigTypeTag()) {7411 switch (operand_ty.zigTypeTag()) {
7394 .Type,7412 .Type,
...@@ -7436,7 +7454,7 @@ fn zirSwitchCond(...@@ -7436,7 +7454,7 @@ fn zirSwitchCond(
7436 .Vector,7454 .Vector,
7437 .Frame,7455 .Frame,
7438 .AnyFrame,7456 .AnyFrame,
7439 => return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(target)}),7457 => return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(sema.mod)}),
7440 }7458 }
7441}7459}
74427460
...@@ -7588,10 +7606,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7588,10 +7606,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7588 );7606 );
7589 }7607 }
7590 try sema.mod.errNoteNonLazy(7608 try sema.mod.errNoteNonLazy(
7591 operand_ty.declSrcLoc(),7609 operand_ty.declSrcLoc(sema.mod),
7592 msg,7610 msg,
7593 "enum '{}' declared here",7611 "enum '{}' declared here",
7594 .{operand_ty.fmt(target)},7612 .{operand_ty.fmt(sema.mod)},
7595 );7613 );
7596 break :msg msg;7614 break :msg msg;
7597 };7615 };
...@@ -7705,10 +7723,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7705,10 +7723,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
77057723
7706 if (maybe_msg) |msg| {7724 if (maybe_msg) |msg| {
7707 try sema.mod.errNoteNonLazy(7725 try sema.mod.errNoteNonLazy(
7708 operand_ty.declSrcLoc(),7726 operand_ty.declSrcLoc(sema.mod),
7709 msg,7727 msg,
7710 "error set '{}' declared here",7728 "error set '{}' declared here",
7711 .{operand_ty.fmt(target)},7729 .{operand_ty.fmt(sema.mod)},
7712 );7730 );
7713 return sema.failWithOwnedErrorMsg(block, msg);7731 return sema.failWithOwnedErrorMsg(block, msg);
7714 }7732 }
...@@ -7738,7 +7756,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7738,7 +7756,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7738 },7756 },
7739 .Union => return sema.fail(block, src, "TODO validate switch .Union", .{}),7757 .Union => return sema.fail(block, src, "TODO validate switch .Union", .{}),
7740 .Int, .ComptimeInt => {7758 .Int, .ComptimeInt => {
7741 var range_set = RangeSet.init(gpa, target);7759 var range_set = RangeSet.init(gpa, sema.mod);
7742 defer range_set.deinit();7760 defer range_set.deinit();
77437761
7744 var extra_index: usize = special.end;7762 var extra_index: usize = special.end;
...@@ -7914,13 +7932,13 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7914,13 +7932,13 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7914 block,7932 block,
7915 src,7933 src,
7916 "else prong required when switching on type '{}'",7934 "else prong required when switching on type '{}'",
7917 .{operand_ty.fmt(target)},7935 .{operand_ty.fmt(sema.mod)},
7918 );7936 );
7919 }7937 }
79207938
7921 var seen_values = ValueSrcMap.initContext(gpa, .{7939 var seen_values = ValueSrcMap.initContext(gpa, .{
7922 .ty = operand_ty,7940 .ty = operand_ty,
7923 .target = target,7941 .mod = sema.mod,
7924 });7942 });
7925 defer seen_values.deinit();7943 defer seen_values.deinit();
79267944
...@@ -7985,7 +8003,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7985,7 +8003,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7985 .ComptimeFloat,8003 .ComptimeFloat,
7986 .Float,8004 .Float,
7987 => return sema.fail(block, operand_src, "invalid switch operand type '{}'", .{8005 => return sema.fail(block, operand_src, "invalid switch operand type '{}'", .{
7988 operand_ty.fmt(target),8006 operand_ty.fmt(sema.mod),
7989 }),8007 }),
7990 }8008 }
79918009
...@@ -8035,7 +8053,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8035,7 +8053,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8035 const item = sema.resolveInst(item_ref);8053 const item = sema.resolveInst(item_ref);
8036 // Validation above ensured these will succeed.8054 // Validation above ensured these will succeed.
8037 const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable;8055 const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable;
8038 if (operand_val.eql(item_val, operand_ty, target)) {8056 if (operand_val.eql(item_val, operand_ty, sema.mod)) {
8039 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);8057 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);
8040 }8058 }
8041 }8059 }
...@@ -8057,7 +8075,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8057,7 +8075,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8057 const item = sema.resolveInst(item_ref);8075 const item = sema.resolveInst(item_ref);
8058 // Validation above ensured these will succeed.8076 // Validation above ensured these will succeed.
8059 const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable;8077 const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable;
8060 if (operand_val.eql(item_val, operand_ty, target)) {8078 if (operand_val.eql(item_val, operand_ty, sema.mod)) {
8061 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);8079 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);
8062 }8080 }
8063 }8081 }
...@@ -8072,8 +8090,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8072,8 +8090,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8072 // Validation above ensured these will succeed.8090 // Validation above ensured these will succeed.
8073 const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first) catch unreachable;8091 const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first) catch unreachable;
8074 const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last) catch unreachable;8092 const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last) catch unreachable;
8075 if (Value.compare(operand_val, .gte, first_tv.val, operand_ty, target) and8093 if (Value.compare(operand_val, .gte, first_tv.val, operand_ty, sema.mod) and
8076 Value.compare(operand_val, .lte, last_tv.val, operand_ty, target))8094 Value.compare(operand_val, .lte, last_tv.val, operand_ty, sema.mod))
8077 {8095 {
8078 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);8096 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);
8079 }8097 }
...@@ -8385,7 +8403,7 @@ fn resolveSwitchItemVal(...@@ -8385,7 +8403,7 @@ fn resolveSwitchItemVal(
8385 return TypedValue{ .ty = item_ty, .val = val };8403 return TypedValue{ .ty = item_ty, .val = val };
8386 } else |err| switch (err) {8404 } else |err| switch (err) {
8387 error.NeededSourceLocation => {8405 error.NeededSourceLocation => {
8388 const src = switch_prong_src.resolve(sema.gpa, block.src_decl, switch_node_offset, range_expand);8406 const src = switch_prong_src.resolve(sema.gpa, sema.mod.declPtr(block.src_decl), switch_node_offset, range_expand);
8389 return TypedValue{8407 return TypedValue{
8390 .ty = item_ty,8408 .ty = item_ty,
8391 .val = try sema.resolveConstValue(block, src, item),8409 .val = try sema.resolveConstValue(block, src, item),
...@@ -8434,19 +8452,18 @@ fn validateSwitchItemEnum(...@@ -8434,19 +8452,18 @@ fn validateSwitchItemEnum(
8434 switch_prong_src: Module.SwitchProngSrc,8452 switch_prong_src: Module.SwitchProngSrc,
8435) CompileError!void {8453) CompileError!void {
8436 const item_tv = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none);8454 const item_tv = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none);
8437 const target = sema.mod.getTarget();8455 const field_index = item_tv.ty.enumTagFieldIndex(item_tv.val, sema.mod) orelse {
8438 const field_index = item_tv.ty.enumTagFieldIndex(item_tv.val, target) orelse {
8439 const msg = msg: {8456 const msg = msg: {
8440 const src = switch_prong_src.resolve(sema.gpa, block.src_decl, src_node_offset, .none);8457 const src = switch_prong_src.resolve(sema.gpa, sema.mod.declPtr(block.src_decl), src_node_offset, .none);
8441 const msg = try sema.errMsg(8458 const msg = try sema.errMsg(
8442 block,8459 block,
8443 src,8460 src,
8444 "enum '{}' has no tag with value '{}'",8461 "enum '{}' has no tag with value '{}'",
8445 .{ item_tv.ty.fmt(target), item_tv.val.fmtValue(item_tv.ty, target) },8462 .{ item_tv.ty.fmt(sema.mod), item_tv.val.fmtValue(item_tv.ty, sema.mod) },
8446 );8463 );
8447 errdefer msg.destroy(sema.gpa);8464 errdefer msg.destroy(sema.gpa);
8448 try sema.mod.errNoteNonLazy(8465 try sema.mod.errNoteNonLazy(
8449 item_tv.ty.declSrcLoc(),8466 item_tv.ty.declSrcLoc(sema.mod),
8450 msg,8467 msg,
8451 "enum declared here",8468 "enum declared here",
8452 .{},8469 .{},
...@@ -8487,8 +8504,9 @@ fn validateSwitchDupe(...@@ -8487,8 +8504,9 @@ fn validateSwitchDupe(
8487) CompileError!void {8504) CompileError!void {
8488 const prev_prong_src = maybe_prev_src orelse return;8505 const prev_prong_src = maybe_prev_src orelse return;
8489 const gpa = sema.gpa;8506 const gpa = sema.gpa;
8490 const src = switch_prong_src.resolve(gpa, block.src_decl, src_node_offset, .none);8507 const block_src_decl = sema.mod.declPtr(block.src_decl);
8491 const prev_src = prev_prong_src.resolve(gpa, block.src_decl, src_node_offset, .none);8508 const src = switch_prong_src.resolve(gpa, block_src_decl, src_node_offset, .none);
8509 const prev_src = prev_prong_src.resolve(gpa, block_src_decl, src_node_offset, .none);
8492 const msg = msg: {8510 const msg = msg: {
8493 const msg = try sema.errMsg(8511 const msg = try sema.errMsg(
8494 block,8512 block,
...@@ -8525,7 +8543,8 @@ fn validateSwitchItemBool(...@@ -8525,7 +8543,8 @@ fn validateSwitchItemBool(
8525 false_count.* += 1;8543 false_count.* += 1;
8526 }8544 }
8527 if (true_count.* + false_count.* > 2) {8545 if (true_count.* + false_count.* > 2) {
8528 const src = switch_prong_src.resolve(sema.gpa, block.src_decl, src_node_offset, .none);8546 const block_src_decl = sema.mod.declPtr(block.src_decl);
8547 const src = switch_prong_src.resolve(sema.gpa, block_src_decl, src_node_offset, .none);
8529 return sema.fail(block, src, "duplicate switch value", .{});8548 return sema.fail(block, src, "duplicate switch value", .{});
8530 }8549 }
8531}8550}
...@@ -8558,13 +8577,12 @@ fn validateSwitchNoRange(...@@ -8558,13 +8577,12 @@ fn validateSwitchNoRange(
8558 const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = src_node_offset };8577 const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = src_node_offset };
8559 const range_src: LazySrcLoc = .{ .node_offset_switch_range = src_node_offset };8578 const range_src: LazySrcLoc = .{ .node_offset_switch_range = src_node_offset };
85608579
8561 const target = sema.mod.getTarget();
8562 const msg = msg: {8580 const msg = msg: {
8563 const msg = try sema.errMsg(8581 const msg = try sema.errMsg(
8564 block,8582 block,
8565 operand_src,8583 operand_src,
8566 "ranges not allowed when switching on type '{}'",8584 "ranges not allowed when switching on type '{}'",
8567 .{operand_ty.fmt(target)},8585 .{operand_ty.fmt(sema.mod)},
8568 );8586 );
8569 errdefer msg.destroy(sema.gpa);8587 errdefer msg.destroy(sema.gpa);
8570 try sema.errNote(8588 try sema.errNote(
...@@ -8587,7 +8605,6 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -8587,7 +8605,6 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
8587 const unresolved_ty = try sema.resolveType(block, ty_src, extra.lhs);8605 const unresolved_ty = try sema.resolveType(block, ty_src, extra.lhs);
8588 const field_name = try sema.resolveConstString(block, name_src, extra.rhs);8606 const field_name = try sema.resolveConstString(block, name_src, extra.rhs);
8589 const ty = try sema.resolveTypeFields(block, ty_src, unresolved_ty);8607 const ty = try sema.resolveTypeFields(block, ty_src, unresolved_ty);
8590 const target = sema.mod.getTarget();
85918608
8592 const has_field = hf: {8609 const has_field = hf: {
8593 if (ty.isSlice()) {8610 if (ty.isSlice()) {
...@@ -8610,7 +8627,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -8610,7 +8627,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
8610 .Enum => ty.enumFields().contains(field_name),8627 .Enum => ty.enumFields().contains(field_name),
8611 .Array => mem.eql(u8, field_name, "len"),8628 .Array => mem.eql(u8, field_name, "len"),
8612 else => return sema.fail(block, ty_src, "type '{}' does not support '@hasField'", .{8629 else => return sema.fail(block, ty_src, "type '{}' does not support '@hasField'", .{
8613 ty.fmt(target),8630 ty.fmt(sema.mod),
8614 }),8631 }),
8615 };8632 };
8616 };8633 };
...@@ -8633,7 +8650,8 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -8633,7 +8650,8 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
8633 try checkNamespaceType(sema, block, lhs_src, container_type);8650 try checkNamespaceType(sema, block, lhs_src, container_type);
86348651
8635 const namespace = container_type.getNamespace() orelse return Air.Inst.Ref.bool_false;8652 const namespace = container_type.getNamespace() orelse return Air.Inst.Ref.bool_false;
8636 if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |decl| {8653 if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |decl_index| {
8654 const decl = sema.mod.declPtr(decl_index);
8637 if (decl.is_pub or decl.getFileScope() == block.getFileScope()) {8655 if (decl.is_pub or decl.getFileScope() == block.getFileScope()) {
8638 return Air.Inst.Ref.bool_true;8656 return Air.Inst.Ref.bool_true;
8639 }8657 }
...@@ -8661,8 +8679,9 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -8661,8 +8679,9 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
8661 },8679 },
8662 };8680 };
8663 try mod.semaFile(result.file);8681 try mod.semaFile(result.file);
8664 const file_root_decl = result.file.root_decl.?;8682 const file_root_decl_index = result.file.root_decl.unwrap().?;
8665 try mod.declareDeclDependency(sema.owner_decl, file_root_decl);8683 const file_root_decl = mod.declPtr(file_root_decl_index);
8684 try mod.declareDeclDependency(sema.owner_decl_index, file_root_decl_index);
8666 return sema.addConstant(file_root_decl.ty, file_root_decl.val);8685 return sema.addConstant(file_root_decl.ty, file_root_decl.val);
8667}8686}
86688687
...@@ -8763,7 +8782,7 @@ fn zirShl(...@@ -8763,7 +8782,7 @@ fn zirShl(
8763 }8782 }
8764 const int_info = scalar_ty.intInfo(target);8783 const int_info = scalar_ty.intInfo(target);
8765 const truncated = try shifted.intTrunc(lhs_ty, sema.arena, int_info.signedness, int_info.bits, target);8784 const truncated = try shifted.intTrunc(lhs_ty, sema.arena, int_info.signedness, int_info.bits, target);
8766 if (truncated.compare(.eq, shifted, lhs_ty, target)) {8785 if (truncated.compare(.eq, shifted, lhs_ty, sema.mod)) {
8767 break :val shifted;8786 break :val shifted;
8768 }8787 }
8769 return sema.addConstUndef(lhs_ty);8788 return sema.addConstUndef(lhs_ty);
...@@ -8927,7 +8946,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -8927,7 +8946,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
89278946
8928 if (scalar_type.zigTypeTag() != .Int) {8947 if (scalar_type.zigTypeTag() != .Int) {
8929 return sema.fail(block, src, "unable to perform binary not operation on type '{}'", .{8948 return sema.fail(block, src, "unable to perform binary not operation on type '{}'", .{
8930 operand_type.fmt(target),8949 operand_type.fmt(sema.mod),
8931 });8950 });
8932 }8951 }
89338952
...@@ -8939,7 +8958,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -8939,7 +8958,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
8939 var elem_val_buf: Value.ElemValueBuffer = undefined;8958 var elem_val_buf: Value.ElemValueBuffer = undefined;
8940 const elems = try sema.arena.alloc(Value, vec_len);8959 const elems = try sema.arena.alloc(Value, vec_len);
8941 for (elems) |*elem, i| {8960 for (elems) |*elem, i| {
8942 const elem_val = val.elemValueBuffer(i, &elem_val_buf);8961 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_val_buf);
8943 elem.* = try elem_val.bitwiseNot(scalar_type, sema.arena, target);8962 elem.* = try elem_val.bitwiseNot(scalar_type, sema.arena, target);
8944 }8963 }
8945 return sema.addConstant(8964 return sema.addConstant(
...@@ -9047,14 +9066,13 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -9047,14 +9066,13 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
9047 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };9066 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
9048 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };9067 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
90499068
9050 const target = sema.mod.getTarget();
9051 const lhs_info = (try sema.getArrayCatInfo(block, lhs_src, lhs)) orelse9069 const lhs_info = (try sema.getArrayCatInfo(block, lhs_src, lhs)) orelse
9052 return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty.fmt(target)});9070 return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty.fmt(sema.mod)});
9053 const rhs_info = (try sema.getArrayCatInfo(block, rhs_src, rhs)) orelse9071 const rhs_info = (try sema.getArrayCatInfo(block, rhs_src, rhs)) orelse
9054 return sema.fail(block, rhs_src, "expected array, found '{}'", .{rhs_ty.fmt(target)});9072 return sema.fail(block, rhs_src, "expected array, found '{}'", .{rhs_ty.fmt(sema.mod)});
9055 if (!lhs_info.elem_type.eql(rhs_info.elem_type, target)) {9073 if (!lhs_info.elem_type.eql(rhs_info.elem_type, sema.mod)) {
9056 return sema.fail(block, rhs_src, "expected array of type '{}', found '{}'", .{9074 return sema.fail(block, rhs_src, "expected array of type '{}', found '{}'", .{
9057 lhs_info.elem_type.fmt(target), rhs_ty.fmt(target),9075 lhs_info.elem_type.fmt(sema.mod), rhs_ty.fmt(sema.mod),
9058 });9076 });
9059 }9077 }
90609078
...@@ -9062,7 +9080,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -9062,7 +9080,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
9062 // will catch this if it is a problem.9080 // will catch this if it is a problem.
9063 var res_sent: ?Value = null;9081 var res_sent: ?Value = null;
9064 if (rhs_info.sentinel != null and lhs_info.sentinel != null) {9082 if (rhs_info.sentinel != null and lhs_info.sentinel != null) {
9065 if (rhs_info.sentinel.?.eql(lhs_info.sentinel.?, lhs_info.elem_type, target)) {9083 if (rhs_info.sentinel.?.eql(lhs_info.sentinel.?, lhs_info.elem_type, sema.mod)) {
9066 res_sent = lhs_info.sentinel.?;9084 res_sent = lhs_info.sentinel.?;
9067 }9085 }
9068 }9086 }
...@@ -9084,14 +9102,14 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -9084,14 +9102,14 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
9084 {9102 {
9085 var i: usize = 0;9103 var i: usize = 0;
9086 while (i < lhs_len) : (i += 1) {9104 while (i < lhs_len) : (i += 1) {
9087 const val = try lhs_sub_val.elemValue(sema.arena, i);9105 const val = try lhs_sub_val.elemValue(sema.mod, sema.arena, i);
9088 buf[i] = try val.copy(anon_decl.arena());9106 buf[i] = try val.copy(anon_decl.arena());
9089 }9107 }
9090 }9108 }
9091 {9109 {
9092 var i: usize = 0;9110 var i: usize = 0;
9093 while (i < rhs_len) : (i += 1) {9111 while (i < rhs_len) : (i += 1) {
9094 const val = try rhs_sub_val.elemValue(sema.arena, i);9112 const val = try rhs_sub_val.elemValue(sema.mod, sema.arena, i);
9095 buf[lhs_len + i] = try val.copy(anon_decl.arena());9113 buf[lhs_len + i] = try val.copy(anon_decl.arena());
9096 }9114 }
9097 }9115 }
...@@ -9123,7 +9141,6 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -9123,7 +9141,6 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
91239141
9124fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, inst: Air.Inst.Ref) !?Type.ArrayInfo {9142fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, inst: Air.Inst.Ref) !?Type.ArrayInfo {
9125 const t = sema.typeOf(inst);9143 const t = sema.typeOf(inst);
9126 const target = sema.mod.getTarget();
9127 return switch (t.zigTypeTag()) {9144 return switch (t.zigTypeTag()) {
9128 .Array => t.arrayInfo(),9145 .Array => t.arrayInfo(),
9129 .Pointer => blk: {9146 .Pointer => blk: {
...@@ -9133,7 +9150,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, inst: Air.Inst.R...@@ -9133,7 +9150,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, inst: Air.Inst.R
9133 return Type.ArrayInfo{9150 return Type.ArrayInfo{
9134 .elem_type = t.childType(),9151 .elem_type = t.childType(),
9135 .sentinel = t.sentinel(),9152 .sentinel = t.sentinel(),
9136 .len = val.sliceLen(target),9153 .len = val.sliceLen(sema.mod),
9137 };9154 };
9138 }9155 }
9139 if (ptrinfo.pointee_type.zigTypeTag() != .Array) return null;9156 if (ptrinfo.pointee_type.zigTypeTag() != .Array) return null;
...@@ -9229,10 +9246,9 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -9229,10 +9246,9 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
9229 if (lhs_ty.isTuple()) {9246 if (lhs_ty.isTuple()) {
9230 return sema.analyzeTupleMul(block, inst_data.src_node, lhs, factor);9247 return sema.analyzeTupleMul(block, inst_data.src_node, lhs, factor);
9231 }9248 }
9232 const target = sema.mod.getTarget();
92339249
9234 const mulinfo = (try sema.getArrayCatInfo(block, lhs_src, lhs)) orelse9250 const mulinfo = (try sema.getArrayCatInfo(block, lhs_src, lhs)) orelse
9235 return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty.fmt(target)});9251 return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty.fmt(sema.mod)});
92369252
9237 const final_len_u64 = std.math.mul(u64, mulinfo.len, factor) catch9253 const final_len_u64 = std.math.mul(u64, mulinfo.len, factor) catch
9238 return sema.fail(block, rhs_src, "operation results in overflow", .{});9254 return sema.fail(block, rhs_src, "operation results in overflow", .{});
...@@ -9264,7 +9280,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -9264,7 +9280,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
9264 // Optimization for the common pattern of a single element repeated N times, such9280 // Optimization for the common pattern of a single element repeated N times, such
9265 // as zero-filling a byte array.9281 // as zero-filling a byte array.
9266 const val = if (lhs_len == 1) blk: {9282 const val = if (lhs_len == 1) blk: {
9267 const elem_val = try lhs_sub_val.elemValue(sema.arena, 0);9283 const elem_val = try lhs_sub_val.elemValue(sema.mod, sema.arena, 0);
9268 const copied_val = try elem_val.copy(anon_decl.arena());9284 const copied_val = try elem_val.copy(anon_decl.arena());
9269 break :blk try Value.Tag.repeated.create(anon_decl.arena(), copied_val);9285 break :blk try Value.Tag.repeated.create(anon_decl.arena(), copied_val);
9270 } else blk: {9286 } else blk: {
...@@ -9273,7 +9289,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -9273,7 +9289,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
9273 while (i < factor) : (i += 1) {9289 while (i < factor) : (i += 1) {
9274 var j: usize = 0;9290 var j: usize = 0;
9275 while (j < lhs_len) : (j += 1) {9291 while (j < lhs_len) : (j += 1) {
9276 const val = try lhs_sub_val.elemValue(sema.arena, j);9292 const val = try lhs_sub_val.elemValue(sema.mod, sema.arena, j);
9277 buf[lhs_len * i + j] = try val.copy(anon_decl.arena());9293 buf[lhs_len * i + j] = try val.copy(anon_decl.arena());
9278 }9294 }
9279 }9295 }
...@@ -9310,9 +9326,8 @@ fn zirNegate(...@@ -9310,9 +9326,8 @@ fn zirNegate(
9310 const rhs_ty = sema.typeOf(rhs);9326 const rhs_ty = sema.typeOf(rhs);
9311 const rhs_scalar_ty = rhs_ty.scalarType();9327 const rhs_scalar_ty = rhs_ty.scalarType();
93129328
9313 const target = sema.mod.getTarget();
9314 if (tag_override == .sub and rhs_scalar_ty.isUnsignedInt()) {9329 if (tag_override == .sub and rhs_scalar_ty.isUnsignedInt()) {
9315 return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(target)});9330 return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(sema.mod)});
9316 }9331 }
93179332
9318 const lhs = if (rhs_ty.zigTypeTag() == .Vector)9333 const lhs = if (rhs_ty.zigTypeTag() == .Vector)
...@@ -9364,12 +9379,13 @@ fn zirOverflowArithmetic(...@@ -9364,12 +9379,13 @@ fn zirOverflowArithmetic(
9364 const ptr = sema.resolveInst(extra.ptr);9379 const ptr = sema.resolveInst(extra.ptr);
93659380
9366 const lhs_ty = sema.typeOf(lhs);9381 const lhs_ty = sema.typeOf(lhs);
9367 const target = sema.mod.getTarget();9382 const mod = sema.mod;
9383 const target = mod.getTarget();
93689384
9369 // Note, the types of lhs/rhs (also for shifting)/ptr are already correct as ensured by astgen.9385 // Note, the types of lhs/rhs (also for shifting)/ptr are already correct as ensured by astgen.
9370 const dest_ty = lhs_ty;9386 const dest_ty = lhs_ty;
9371 if (dest_ty.zigTypeTag() != .Int) {9387 if (dest_ty.zigTypeTag() != .Int) {
9372 return sema.fail(block, src, "expected integer type, found '{}'", .{dest_ty.fmt(target)});9388 return sema.fail(block, src, "expected integer type, found '{}'", .{dest_ty.fmt(mod)});
9373 }9389 }
93749390
9375 const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, lhs);9391 const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, lhs);
...@@ -9445,7 +9461,7 @@ fn zirOverflowArithmetic(...@@ -9445,7 +9461,7 @@ fn zirOverflowArithmetic(
9445 if (!lhs_val.isUndef()) {9461 if (!lhs_val.isUndef()) {
9446 if (lhs_val.compareWithZero(.eq)) {9462 if (lhs_val.compareWithZero(.eq)) {
9447 break :result .{ .overflowed = .no, .wrapped = lhs };9463 break :result .{ .overflowed = .no, .wrapped = lhs };
9448 } else if (lhs_val.compare(.eq, Value.one, dest_ty, target)) {9464 } else if (lhs_val.compare(.eq, Value.one, dest_ty, mod)) {
9449 break :result .{ .overflowed = .no, .wrapped = rhs };9465 break :result .{ .overflowed = .no, .wrapped = rhs };
9450 }9466 }
9451 }9467 }
...@@ -9455,7 +9471,7 @@ fn zirOverflowArithmetic(...@@ -9455,7 +9471,7 @@ fn zirOverflowArithmetic(
9455 if (!rhs_val.isUndef()) {9471 if (!rhs_val.isUndef()) {
9456 if (rhs_val.compareWithZero(.eq)) {9472 if (rhs_val.compareWithZero(.eq)) {
9457 break :result .{ .overflowed = .no, .wrapped = rhs };9473 break :result .{ .overflowed = .no, .wrapped = rhs };
9458 } else if (rhs_val.compare(.eq, Value.one, dest_ty, target)) {9474 } else if (rhs_val.compare(.eq, Value.one, dest_ty, mod)) {
9459 break :result .{ .overflowed = .no, .wrapped = lhs };9475 break :result .{ .overflowed = .no, .wrapped = lhs };
9460 }9476 }
9461 }9477 }
...@@ -9596,7 +9612,8 @@ fn analyzeArithmetic(...@@ -9596,7 +9612,8 @@ fn analyzeArithmetic(
9596 });9612 });
9597 }9613 }
95989614
9599 const target = sema.mod.getTarget();9615 const mod = sema.mod;
9616 const target = mod.getTarget();
9600 const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs);9617 const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs);
9601 const maybe_rhs_val = try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs);9618 const maybe_rhs_val = try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs);
9602 const rs: struct { src: LazySrcLoc, air_tag: Air.Inst.Tag } = rs: {9619 const rs: struct { src: LazySrcLoc, air_tag: Air.Inst.Tag } = rs: {
...@@ -9834,7 +9851,7 @@ fn analyzeArithmetic(...@@ -9834,7 +9851,7 @@ fn analyzeArithmetic(
9834 if (lhs_val.isUndef()) {9851 if (lhs_val.isUndef()) {
9835 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {9852 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {
9836 if (maybe_rhs_val) |rhs_val| {9853 if (maybe_rhs_val) |rhs_val| {
9837 if (rhs_val.compare(.neq, Value.negative_one, resolved_type, target)) {9854 if (rhs_val.compare(.neq, Value.negative_one, resolved_type, mod)) {
9838 return sema.addConstUndef(resolved_type);9855 return sema.addConstUndef(resolved_type);
9839 }9856 }
9840 }9857 }
...@@ -9909,7 +9926,7 @@ fn analyzeArithmetic(...@@ -9909,7 +9926,7 @@ fn analyzeArithmetic(
9909 if (lhs_val.isUndef()) {9926 if (lhs_val.isUndef()) {
9910 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {9927 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {
9911 if (maybe_rhs_val) |rhs_val| {9928 if (maybe_rhs_val) |rhs_val| {
9912 if (rhs_val.compare(.neq, Value.negative_one, resolved_type, target)) {9929 if (rhs_val.compare(.neq, Value.negative_one, resolved_type, mod)) {
9913 return sema.addConstUndef(resolved_type);9930 return sema.addConstUndef(resolved_type);
9914 }9931 }
9915 }9932 }
...@@ -9972,7 +9989,7 @@ fn analyzeArithmetic(...@@ -9972,7 +9989,7 @@ fn analyzeArithmetic(
9972 if (lhs_val.isUndef()) {9989 if (lhs_val.isUndef()) {
9973 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {9990 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {
9974 if (maybe_rhs_val) |rhs_val| {9991 if (maybe_rhs_val) |rhs_val| {
9975 if (rhs_val.compare(.neq, Value.negative_one, resolved_type, target)) {9992 if (rhs_val.compare(.neq, Value.negative_one, resolved_type, mod)) {
9976 return sema.addConstUndef(resolved_type);9993 return sema.addConstUndef(resolved_type);
9977 }9994 }
9978 }9995 }
...@@ -10062,7 +10079,7 @@ fn analyzeArithmetic(...@@ -10062,7 +10079,7 @@ fn analyzeArithmetic(
10062 if (lhs_val.compareWithZero(.eq)) {10079 if (lhs_val.compareWithZero(.eq)) {
10063 return sema.addConstant(resolved_type, Value.zero);10080 return sema.addConstant(resolved_type, Value.zero);
10064 }10081 }
10065 if (lhs_val.compare(.eq, Value.one, resolved_type, target)) {10082 if (lhs_val.compare(.eq, Value.one, resolved_type, mod)) {
10066 return casted_rhs;10083 return casted_rhs;
10067 }10084 }
10068 }10085 }
...@@ -10078,7 +10095,7 @@ fn analyzeArithmetic(...@@ -10078,7 +10095,7 @@ fn analyzeArithmetic(
10078 if (rhs_val.compareWithZero(.eq)) {10095 if (rhs_val.compareWithZero(.eq)) {
10079 return sema.addConstant(resolved_type, Value.zero);10096 return sema.addConstant(resolved_type, Value.zero);
10080 }10097 }
10081 if (rhs_val.compare(.eq, Value.one, resolved_type, target)) {10098 if (rhs_val.compare(.eq, Value.one, resolved_type, mod)) {
10082 return casted_lhs;10099 return casted_lhs;
10083 }10100 }
10084 if (maybe_lhs_val) |lhs_val| {10101 if (maybe_lhs_val) |lhs_val| {
...@@ -10113,7 +10130,7 @@ fn analyzeArithmetic(...@@ -10113,7 +10130,7 @@ fn analyzeArithmetic(
10113 if (lhs_val.compareWithZero(.eq)) {10130 if (lhs_val.compareWithZero(.eq)) {
10114 return sema.addConstant(resolved_type, Value.zero);10131 return sema.addConstant(resolved_type, Value.zero);
10115 }10132 }
10116 if (lhs_val.compare(.eq, Value.one, resolved_type, target)) {10133 if (lhs_val.compare(.eq, Value.one, resolved_type, mod)) {
10117 return casted_rhs;10134 return casted_rhs;
10118 }10135 }
10119 }10136 }
...@@ -10125,7 +10142,7 @@ fn analyzeArithmetic(...@@ -10125,7 +10142,7 @@ fn analyzeArithmetic(
10125 if (rhs_val.compareWithZero(.eq)) {10142 if (rhs_val.compareWithZero(.eq)) {
10126 return sema.addConstant(resolved_type, Value.zero);10143 return sema.addConstant(resolved_type, Value.zero);
10127 }10144 }
10128 if (rhs_val.compare(.eq, Value.one, resolved_type, target)) {10145 if (rhs_val.compare(.eq, Value.one, resolved_type, mod)) {
10129 return casted_lhs;10146 return casted_lhs;
10130 }10147 }
10131 if (maybe_lhs_val) |lhs_val| {10148 if (maybe_lhs_val) |lhs_val| {
...@@ -10149,7 +10166,7 @@ fn analyzeArithmetic(...@@ -10149,7 +10166,7 @@ fn analyzeArithmetic(
10149 if (lhs_val.compareWithZero(.eq)) {10166 if (lhs_val.compareWithZero(.eq)) {
10150 return sema.addConstant(resolved_type, Value.zero);10167 return sema.addConstant(resolved_type, Value.zero);
10151 }10168 }
10152 if (lhs_val.compare(.eq, Value.one, resolved_type, target)) {10169 if (lhs_val.compare(.eq, Value.one, resolved_type, mod)) {
10153 return casted_rhs;10170 return casted_rhs;
10154 }10171 }
10155 }10172 }
...@@ -10161,7 +10178,7 @@ fn analyzeArithmetic(...@@ -10161,7 +10178,7 @@ fn analyzeArithmetic(
10161 if (rhs_val.compareWithZero(.eq)) {10178 if (rhs_val.compareWithZero(.eq)) {
10162 return sema.addConstant(resolved_type, Value.zero);10179 return sema.addConstant(resolved_type, Value.zero);
10163 }10180 }
10164 if (rhs_val.compare(.eq, Value.one, resolved_type, target)) {10181 if (rhs_val.compare(.eq, Value.one, resolved_type, mod)) {
10165 return casted_lhs;10182 return casted_lhs;
10166 }10183 }
10167 if (maybe_lhs_val) |lhs_val| {10184 if (maybe_lhs_val) |lhs_val| {
...@@ -10431,7 +10448,7 @@ fn analyzePtrArithmetic(...@@ -10431,7 +10448,7 @@ fn analyzePtrArithmetic(
10431 if (air_tag == .ptr_sub) {10448 if (air_tag == .ptr_sub) {
10432 return sema.fail(block, op_src, "TODO implement Sema comptime pointer subtraction", .{});10449 return sema.fail(block, op_src, "TODO implement Sema comptime pointer subtraction", .{});
10433 }10450 }
10434 const new_ptr_val = try ptr_val.elemPtr(ptr_ty, sema.arena, offset_int, target);10451 const new_ptr_val = try ptr_val.elemPtr(ptr_ty, sema.arena, offset_int, sema.mod);
10435 return sema.addConstant(new_ptr_ty, new_ptr_val);10452 return sema.addConstant(new_ptr_ty, new_ptr_val);
10436 } else break :rs offset_src;10453 } else break :rs offset_src;
10437 } else break :rs ptr_src;10454 } else break :rs ptr_src;
...@@ -10605,7 +10622,6 @@ fn zirCmpEq(...@@ -10605,7 +10622,6 @@ fn zirCmpEq(
10605 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };10622 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
10606 const lhs = sema.resolveInst(extra.lhs);10623 const lhs = sema.resolveInst(extra.lhs);
10607 const rhs = sema.resolveInst(extra.rhs);10624 const rhs = sema.resolveInst(extra.rhs);
10608 const target = sema.mod.getTarget();
1060910625
10610 const lhs_ty = sema.typeOf(lhs);10626 const lhs_ty = sema.typeOf(lhs);
10611 const rhs_ty = sema.typeOf(rhs);10627 const rhs_ty = sema.typeOf(rhs);
...@@ -10630,7 +10646,7 @@ fn zirCmpEq(...@@ -10630,7 +10646,7 @@ fn zirCmpEq(
1063010646
10631 if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) {10647 if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) {
10632 const non_null_type = if (lhs_ty_tag == .Null) rhs_ty else lhs_ty;10648 const non_null_type = if (lhs_ty_tag == .Null) rhs_ty else lhs_ty;
10633 return sema.fail(block, src, "comparison of '{}' with null", .{non_null_type.fmt(target)});10649 return sema.fail(block, src, "comparison of '{}' with null", .{non_null_type.fmt(sema.mod)});
10634 }10650 }
1063510651
10636 if (lhs_ty_tag == .Union and (rhs_ty_tag == .EnumLiteral or rhs_ty_tag == .Enum)) {10652 if (lhs_ty_tag == .Union and (rhs_ty_tag == .EnumLiteral or rhs_ty_tag == .Enum)) {
...@@ -10670,7 +10686,7 @@ fn zirCmpEq(...@@ -10670,7 +10686,7 @@ fn zirCmpEq(
10670 if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) {10686 if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) {
10671 const lhs_as_type = try sema.analyzeAsType(block, lhs_src, lhs);10687 const lhs_as_type = try sema.analyzeAsType(block, lhs_src, lhs);
10672 const rhs_as_type = try sema.analyzeAsType(block, rhs_src, rhs);10688 const rhs_as_type = try sema.analyzeAsType(block, rhs_src, rhs);
10673 if (lhs_as_type.eql(rhs_as_type, target) == (op == .eq)) {10689 if (lhs_as_type.eql(rhs_as_type, sema.mod) == (op == .eq)) {
10674 return Air.Inst.Ref.bool_true;10690 return Air.Inst.Ref.bool_true;
10675 } else {10691 } else {
10676 return Air.Inst.Ref.bool_false;10692 return Air.Inst.Ref.bool_false;
...@@ -10747,10 +10763,9 @@ fn analyzeCmp(...@@ -10747,10 +10763,9 @@ fn analyzeCmp(
10747 }10763 }
10748 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };10764 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
10749 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } });10765 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } });
10750 const target = sema.mod.getTarget();
10751 if (!resolved_type.isSelfComparable(is_equality_cmp)) {10766 if (!resolved_type.isSelfComparable(is_equality_cmp)) {
10752 return sema.fail(block, src, "{s} operator not allowed for type '{}'", .{10767 return sema.fail(block, src, "{s} operator not allowed for type '{}'", .{
10753 @tagName(op), resolved_type.fmt(target),10768 @tagName(op), resolved_type.fmt(sema.mod),
10754 });10769 });
10755 }10770 }
10756 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);10771 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
...@@ -10768,7 +10783,6 @@ fn cmpSelf(...@@ -10768,7 +10783,6 @@ fn cmpSelf(
10768 rhs_src: LazySrcLoc,10783 rhs_src: LazySrcLoc,
10769) CompileError!Air.Inst.Ref {10784) CompileError!Air.Inst.Ref {
10770 const resolved_type = sema.typeOf(casted_lhs);10785 const resolved_type = sema.typeOf(casted_lhs);
10771 const target = sema.mod.getTarget();
10772 const runtime_src: LazySrcLoc = src: {10786 const runtime_src: LazySrcLoc = src: {
10773 if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| {10787 if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| {
10774 if (lhs_val.isUndef()) return sema.addConstUndef(Type.bool);10788 if (lhs_val.isUndef()) return sema.addConstUndef(Type.bool);
...@@ -10777,11 +10791,11 @@ fn cmpSelf(...@@ -10777,11 +10791,11 @@ fn cmpSelf(
1077710791
10778 if (resolved_type.zigTypeTag() == .Vector) {10792 if (resolved_type.zigTypeTag() == .Vector) {
10779 const result_ty = try Type.vector(sema.arena, resolved_type.vectorLen(), Type.@"bool");10793 const result_ty = try Type.vector(sema.arena, resolved_type.vectorLen(), Type.@"bool");
10780 const cmp_val = try lhs_val.compareVector(op, rhs_val, resolved_type, sema.arena, target);10794 const cmp_val = try lhs_val.compareVector(op, rhs_val, resolved_type, sema.arena, sema.mod);
10781 return sema.addConstant(result_ty, cmp_val);10795 return sema.addConstant(result_ty, cmp_val);
10782 }10796 }
1078310797
10784 if (lhs_val.compare(op, rhs_val, resolved_type, target)) {10798 if (lhs_val.compare(op, rhs_val, resolved_type, sema.mod)) {
10785 return Air.Inst.Ref.bool_true;10799 return Air.Inst.Ref.bool_true;
10786 } else {10800 } else {
10787 return Air.Inst.Ref.bool_false;10801 return Air.Inst.Ref.bool_false;
...@@ -10849,7 +10863,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -10849,7 +10863,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
10849 .Null,10863 .Null,
10850 .BoundFn,10864 .BoundFn,
10851 .Opaque,10865 .Opaque,
10852 => return sema.fail(block, src, "no size available for type '{}'", .{operand_ty.fmt(target)}),10866 => return sema.fail(block, src, "no size available for type '{}'", .{operand_ty.fmt(sema.mod)}),
1085310867
10854 .Type,10868 .Type,
10855 .EnumLiteral,10869 .EnumLiteral,
...@@ -10892,9 +10906,9 @@ fn zirThis(...@@ -10892,9 +10906,9 @@ fn zirThis(
10892 block: *Block,10906 block: *Block,
10893 extended: Zir.Inst.Extended.InstData,10907 extended: Zir.Inst.Extended.InstData,
10894) CompileError!Air.Inst.Ref {10908) CompileError!Air.Inst.Ref {
10895 const this_decl = block.namespace.getDecl();10909 const this_decl_index = block.namespace.getDeclIndex();
10896 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };10910 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
10897 return sema.analyzeDeclVal(block, src, this_decl);10911 return sema.analyzeDeclVal(block, src, this_decl_index);
10898}10912}
1089910913
10900fn zirClosureCapture(10914fn zirClosureCapture(
...@@ -10927,7 +10941,7 @@ fn zirClosureGet(...@@ -10927,7 +10941,7 @@ fn zirClosureGet(
10927) CompileError!Air.Inst.Ref {10941) CompileError!Air.Inst.Ref {
10928 // TODO CLOSURE: Test this with inline functions10942 // TODO CLOSURE: Test this with inline functions
10929 const inst_data = sema.code.instructions.items(.data)[inst].inst_node;10943 const inst_data = sema.code.instructions.items(.data)[inst].inst_node;
10930 var scope: *CaptureScope = block.src_decl.src_scope.?;10944 var scope: *CaptureScope = sema.mod.declPtr(block.src_decl).src_scope.?;
10931 // Note: The target closure must be in this scope list.10945 // Note: The target closure must be in this scope list.
10932 // If it's not here, the zir is invalid, or the list is broken.10946 // If it's not here, the zir is invalid, or the list is broken.
10933 const tv = while (true) {10947 const tv = while (true) {
...@@ -10973,11 +10987,12 @@ fn zirBuiltinSrc(...@@ -10973,11 +10987,12 @@ fn zirBuiltinSrc(
10973 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };10987 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
10974 const extra = sema.code.extraData(Zir.Inst.LineColumn, extended.operand).data;10988 const extra = sema.code.extraData(Zir.Inst.LineColumn, extended.operand).data;
10975 const func = sema.func orelse return sema.fail(block, src, "@src outside function", .{});10989 const func = sema.func orelse return sema.fail(block, src, "@src outside function", .{});
10990 const fn_owner_decl = sema.mod.declPtr(func.owner_decl);
1097610991
10977 const func_name_val = blk: {10992 const func_name_val = blk: {
10978 var anon_decl = try block.startAnonDecl(src);10993 var anon_decl = try block.startAnonDecl(src);
10979 defer anon_decl.deinit();10994 defer anon_decl.deinit();
10980 const name = std.mem.span(func.owner_decl.name);10995 const name = std.mem.span(fn_owner_decl.name);
10981 const bytes = try anon_decl.arena().dupe(u8, name[0 .. name.len + 1]);10996 const bytes = try anon_decl.arena().dupe(u8, name[0 .. name.len + 1]);
10982 const new_decl = try anon_decl.finish(10997 const new_decl = try anon_decl.finish(
10983 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len - 1),10998 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len - 1),
...@@ -10990,7 +11005,7 @@ fn zirBuiltinSrc(...@@ -10990,7 +11005,7 @@ fn zirBuiltinSrc(
10990 const file_name_val = blk: {11005 const file_name_val = blk: {
10991 var anon_decl = try block.startAnonDecl(src);11006 var anon_decl = try block.startAnonDecl(src);
10992 defer anon_decl.deinit();11007 defer anon_decl.deinit();
10993 const name = try func.owner_decl.getFileScope().fullPathZ(anon_decl.arena());11008 const name = try fn_owner_decl.getFileScope().fullPathZ(anon_decl.arena());
10994 const new_decl = try anon_decl.finish(11009 const new_decl = try anon_decl.finish(
10995 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), name.len),11010 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), name.len),
10996 try Value.Tag.bytes.create(anon_decl.arena(), name[0 .. name.len + 1]),11011 try Value.Tag.bytes.create(anon_decl.arena(), name[0 .. name.len + 1]),
...@@ -11118,24 +11133,26 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -11118,24 +11133,26 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
11118 }11133 }
1111911134
11120 const args_val = v: {11135 const args_val = v: {
11121 const fn_info_decl = (try sema.namespaceLookup(11136 const fn_info_decl_index = (try sema.namespaceLookup(
11122 block,11137 block,
11123 src,11138 src,
11124 type_info_ty.getNamespace().?,11139 type_info_ty.getNamespace().?,
11125 "Fn",11140 "Fn",
11126 )).?;11141 )).?;
11127 try sema.mod.declareDeclDependency(sema.owner_decl, fn_info_decl);11142 try sema.mod.declareDeclDependency(sema.owner_decl_index, fn_info_decl_index);
11128 try sema.ensureDeclAnalyzed(fn_info_decl);11143 try sema.ensureDeclAnalyzed(fn_info_decl_index);
11144 const fn_info_decl = sema.mod.declPtr(fn_info_decl_index);
11129 var fn_ty_buffer: Value.ToTypeBuffer = undefined;11145 var fn_ty_buffer: Value.ToTypeBuffer = undefined;
11130 const fn_ty = fn_info_decl.val.toType(&fn_ty_buffer);11146 const fn_ty = fn_info_decl.val.toType(&fn_ty_buffer);
11131 const param_info_decl = (try sema.namespaceLookup(11147 const param_info_decl_index = (try sema.namespaceLookup(
11132 block,11148 block,
11133 src,11149 src,
11134 fn_ty.getNamespace().?,11150 fn_ty.getNamespace().?,
11135 "Param",11151 "Param",
11136 )).?;11152 )).?;
11137 try sema.mod.declareDeclDependency(sema.owner_decl, param_info_decl);11153 try sema.mod.declareDeclDependency(sema.owner_decl_index, param_info_decl_index);
11138 try sema.ensureDeclAnalyzed(param_info_decl);11154 try sema.ensureDeclAnalyzed(param_info_decl_index);
11155 const param_info_decl = sema.mod.declPtr(param_info_decl_index);
11139 var param_buffer: Value.ToTypeBuffer = undefined;11156 var param_buffer: Value.ToTypeBuffer = undefined;
11140 const param_ty = param_info_decl.val.toType(&param_buffer);11157 const param_ty = param_info_decl.val.toType(&param_buffer);
11141 const new_decl = try params_anon_decl.finish(11158 const new_decl = try params_anon_decl.finish(
...@@ -11307,14 +11324,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -11307,14 +11324,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1130711324
11308 // Get the Error type11325 // Get the Error type
11309 const error_field_ty = t: {11326 const error_field_ty = t: {
11310 const set_field_ty_decl = (try sema.namespaceLookup(11327 const set_field_ty_decl_index = (try sema.namespaceLookup(
11311 block,11328 block,
11312 src,11329 src,
11313 type_info_ty.getNamespace().?,11330 type_info_ty.getNamespace().?,
11314 "Error",11331 "Error",
11315 )).?;11332 )).?;
11316 try sema.mod.declareDeclDependency(sema.owner_decl, set_field_ty_decl);11333 try sema.mod.declareDeclDependency(sema.owner_decl_index, set_field_ty_decl_index);
11317 try sema.ensureDeclAnalyzed(set_field_ty_decl);11334 try sema.ensureDeclAnalyzed(set_field_ty_decl_index);
11335 const set_field_ty_decl = sema.mod.declPtr(set_field_ty_decl_index);
11318 var buffer: Value.ToTypeBuffer = undefined;11336 var buffer: Value.ToTypeBuffer = undefined;
11319 break :t try set_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena());11337 break :t try set_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena());
11320 };11338 };
...@@ -11416,14 +11434,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -11416,14 +11434,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
11416 defer fields_anon_decl.deinit();11434 defer fields_anon_decl.deinit();
1141711435
11418 const enum_field_ty = t: {11436 const enum_field_ty = t: {
11419 const enum_field_ty_decl = (try sema.namespaceLookup(11437 const enum_field_ty_decl_index = (try sema.namespaceLookup(
11420 block,11438 block,
11421 src,11439 src,
11422 type_info_ty.getNamespace().?,11440 type_info_ty.getNamespace().?,
11423 "EnumField",11441 "EnumField",
11424 )).?;11442 )).?;
11425 try sema.mod.declareDeclDependency(sema.owner_decl, enum_field_ty_decl);11443 try sema.mod.declareDeclDependency(sema.owner_decl_index, enum_field_ty_decl_index);
11426 try sema.ensureDeclAnalyzed(enum_field_ty_decl);11444 try sema.ensureDeclAnalyzed(enum_field_ty_decl_index);
11445 const enum_field_ty_decl = sema.mod.declPtr(enum_field_ty_decl_index);
11427 var buffer: Value.ToTypeBuffer = undefined;11446 var buffer: Value.ToTypeBuffer = undefined;
11428 break :t try enum_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena());11447 break :t try enum_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena());
11429 };11448 };
...@@ -11514,14 +11533,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -11514,14 +11533,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
11514 defer fields_anon_decl.deinit();11533 defer fields_anon_decl.deinit();
1151511534
11516 const union_field_ty = t: {11535 const union_field_ty = t: {
11517 const union_field_ty_decl = (try sema.namespaceLookup(11536 const union_field_ty_decl_index = (try sema.namespaceLookup(
11518 block,11537 block,
11519 src,11538 src,
11520 type_info_ty.getNamespace().?,11539 type_info_ty.getNamespace().?,
11521 "UnionField",11540 "UnionField",
11522 )).?;11541 )).?;
11523 try sema.mod.declareDeclDependency(sema.owner_decl, union_field_ty_decl);11542 try sema.mod.declareDeclDependency(sema.owner_decl_index, union_field_ty_decl_index);
11524 try sema.ensureDeclAnalyzed(union_field_ty_decl);11543 try sema.ensureDeclAnalyzed(union_field_ty_decl_index);
11544 const union_field_ty_decl = sema.mod.declPtr(union_field_ty_decl_index);
11525 var buffer: Value.ToTypeBuffer = undefined;11545 var buffer: Value.ToTypeBuffer = undefined;
11526 break :t try union_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena());11546 break :t try union_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena());
11527 };11547 };
...@@ -11621,14 +11641,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -11621,14 +11641,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
11621 defer fields_anon_decl.deinit();11641 defer fields_anon_decl.deinit();
1162211642
11623 const struct_field_ty = t: {11643 const struct_field_ty = t: {
11624 const struct_field_ty_decl = (try sema.namespaceLookup(11644 const struct_field_ty_decl_index = (try sema.namespaceLookup(
11625 block,11645 block,
11626 src,11646 src,
11627 type_info_ty.getNamespace().?,11647 type_info_ty.getNamespace().?,
11628 "StructField",11648 "StructField",
11629 )).?;11649 )).?;
11630 try sema.mod.declareDeclDependency(sema.owner_decl, struct_field_ty_decl);11650 try sema.mod.declareDeclDependency(sema.owner_decl_index, struct_field_ty_decl_index);
11631 try sema.ensureDeclAnalyzed(struct_field_ty_decl);11651 try sema.ensureDeclAnalyzed(struct_field_ty_decl_index);
11652 const struct_field_ty_decl = sema.mod.declPtr(struct_field_ty_decl_index);
11632 var buffer: Value.ToTypeBuffer = undefined;11653 var buffer: Value.ToTypeBuffer = undefined;
11633 break :t try struct_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena());11654 break :t try struct_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena());
11634 };11655 };
...@@ -11811,14 +11832,15 @@ fn typeInfoDecls(...@@ -11811,14 +11832,15 @@ fn typeInfoDecls(
11811 defer decls_anon_decl.deinit();11832 defer decls_anon_decl.deinit();
1181211833
11813 const declaration_ty = t: {11834 const declaration_ty = t: {
11814 const declaration_ty_decl = (try sema.namespaceLookup(11835 const declaration_ty_decl_index = (try sema.namespaceLookup(
11815 block,11836 block,
11816 src,11837 src,
11817 type_info_ty.getNamespace().?,11838 type_info_ty.getNamespace().?,
11818 "Declaration",11839 "Declaration",
11819 )).?;11840 )).?;
11820 try sema.mod.declareDeclDependency(sema.owner_decl, declaration_ty_decl);11841 try sema.mod.declareDeclDependency(sema.owner_decl_index, declaration_ty_decl_index);
11821 try sema.ensureDeclAnalyzed(declaration_ty_decl);11842 try sema.ensureDeclAnalyzed(declaration_ty_decl_index);
11843 const declaration_ty_decl = sema.mod.declPtr(declaration_ty_decl_index);
11822 var buffer: Value.ToTypeBuffer = undefined;11844 var buffer: Value.ToTypeBuffer = undefined;
11823 break :t try declaration_ty_decl.val.toType(&buffer).copy(decls_anon_decl.arena());11845 break :t try declaration_ty_decl.val.toType(&buffer).copy(decls_anon_decl.arena());
11824 };11846 };
...@@ -11827,7 +11849,8 @@ fn typeInfoDecls(...@@ -11827,7 +11849,8 @@ fn typeInfoDecls(
11827 const decls_len = if (opt_namespace) |ns| ns.decls.count() else 0;11849 const decls_len = if (opt_namespace) |ns| ns.decls.count() else 0;
11828 const decls_vals = try decls_anon_decl.arena().alloc(Value, decls_len);11850 const decls_vals = try decls_anon_decl.arena().alloc(Value, decls_len);
11829 for (decls_vals) |*decls_val, i| {11851 for (decls_vals) |*decls_val, i| {
11830 const decl = opt_namespace.?.decls.keys()[i];11852 const decl_index = opt_namespace.?.decls.keys()[i];
11853 const decl = sema.mod.declPtr(decl_index);
11831 const name_val = v: {11854 const name_val = v: {
11832 var anon_decl = try block.startAnonDecl(src);11855 var anon_decl = try block.startAnonDecl(src);
11833 defer anon_decl.deinit();11856 defer anon_decl.deinit();
...@@ -11947,12 +11970,11 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi...@@ -11947,12 +11970,11 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi
11947 },11970 },
11948 else => {},11971 else => {},
11949 }11972 }
11950 const target = sema.mod.getTarget();
11951 return sema.fail(11973 return sema.fail(
11952 block,11974 block,
11953 src,11975 src,
11954 "bit shifting operation expected integer type, found '{}'",11976 "bit shifting operation expected integer type, found '{}'",
11955 .{operand.fmt(target)},11977 .{operand.fmt(sema.mod)},
11956 );11978 );
11957}11979}
1195811980
...@@ -12426,8 +12448,7 @@ fn zirPtrTypeSimple(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -12426,8 +12448,7 @@ fn zirPtrTypeSimple(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
1242612448
12427 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type_simple;12449 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type_simple;
12428 const elem_type = try sema.resolveType(block, .unneeded, inst_data.elem_type);12450 const elem_type = try sema.resolveType(block, .unneeded, inst_data.elem_type);
12429 const target = sema.mod.getTarget();12451 const ty = try Type.ptr(sema.arena, sema.mod, .{
12430 const ty = try Type.ptr(sema.arena, target, .{
12431 .pointee_type = elem_type,12452 .pointee_type = elem_type,
12432 .@"addrspace" = .generic,12453 .@"addrspace" = .generic,
12433 .mutable = inst_data.is_mutable,12454 .mutable = inst_data.is_mutable,
...@@ -12466,7 +12487,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -12466,7 +12487,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
12466 // Check if this happens to be the lazy alignment of our element type, in12487 // Check if this happens to be the lazy alignment of our element type, in
12467 // which case we can make this 0 without resolving it.12488 // which case we can make this 0 without resolving it.
12468 if (val.castTag(.lazy_align)) |payload| {12489 if (val.castTag(.lazy_align)) |payload| {
12469 if (payload.data.eql(unresolved_elem_ty, target)) {12490 if (payload.data.eql(unresolved_elem_ty, sema.mod)) {
12470 break :blk 0;12491 break :blk 0;
12471 }12492 }
12472 }12493 }
...@@ -12505,7 +12526,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -12505,7 +12526,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
12505 try sema.resolveTypeLayout(block, elem_ty_src, elem_ty);12526 try sema.resolveTypeLayout(block, elem_ty_src, elem_ty);
12506 break :t elem_ty;12527 break :t elem_ty;
12507 };12528 };
12508 const ty = try Type.ptr(sema.arena, target, .{12529 const ty = try Type.ptr(sema.arena, sema.mod, .{
12509 .pointee_type = elem_ty,12530 .pointee_type = elem_ty,
12510 .sentinel = sentinel,12531 .sentinel = sentinel,
12511 .@"align" = abi_align,12532 .@"align" = abi_align,
...@@ -12754,10 +12775,10 @@ fn finishStructInit(...@@ -12754,10 +12775,10 @@ fn finishStructInit(
12754 const gpa = sema.gpa;12775 const gpa = sema.gpa;
1275512776
12756 if (root_msg) |msg| {12777 if (root_msg) |msg| {
12757 const fqn = try struct_obj.getFullyQualifiedName(gpa);12778 const fqn = try struct_obj.getFullyQualifiedName(sema.mod);
12758 defer gpa.free(fqn);12779 defer gpa.free(fqn);
12759 try sema.mod.errNoteNonLazy(12780 try sema.mod.errNoteNonLazy(
12760 struct_obj.srcLoc(),12781 struct_obj.srcLoc(sema.mod),
12761 msg,12782 msg,
12762 "struct '{s}' declared here",12783 "struct '{s}' declared here",
12763 .{fqn},12784 .{fqn},
...@@ -12782,7 +12803,7 @@ fn finishStructInit(...@@ -12782,7 +12803,7 @@ fn finishStructInit(
1278212803
12783 if (is_ref) {12804 if (is_ref) {
12784 const target = sema.mod.getTarget();12805 const target = sema.mod.getTarget();
12785 const alloc_ty = try Type.ptr(sema.arena, target, .{12806 const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{
12786 .pointee_type = struct_ty,12807 .pointee_type = struct_ty,
12787 .@"addrspace" = target_util.defaultAddressSpace(target, .local),12808 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
12788 });12809 });
...@@ -12851,7 +12872,7 @@ fn zirStructInitAnon(...@@ -12851,7 +12872,7 @@ fn zirStructInitAnon(
1285112872
12852 if (is_ref) {12873 if (is_ref) {
12853 const target = sema.mod.getTarget();12874 const target = sema.mod.getTarget();
12854 const alloc_ty = try Type.ptr(sema.arena, target, .{12875 const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{
12855 .pointee_type = tuple_ty,12876 .pointee_type = tuple_ty,
12856 .@"addrspace" = target_util.defaultAddressSpace(target, .local),12877 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
12857 });12878 });
...@@ -12862,7 +12883,7 @@ fn zirStructInitAnon(...@@ -12862,7 +12883,7 @@ fn zirStructInitAnon(
12862 const item = sema.code.extraData(Zir.Inst.StructInitAnon.Item, extra_index);12883 const item = sema.code.extraData(Zir.Inst.StructInitAnon.Item, extra_index);
12863 extra_index = item.end;12884 extra_index = item.end;
1286412885
12865 const field_ptr_ty = try Type.ptr(sema.arena, target, .{12886 const field_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
12866 .mutable = true,12887 .mutable = true,
12867 .@"addrspace" = target_util.defaultAddressSpace(target, .local),12888 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
12868 .pointee_type = field_ty,12889 .pointee_type = field_ty,
...@@ -12949,13 +12970,13 @@ fn zirArrayInit(...@@ -12949,13 +12970,13 @@ fn zirArrayInit(
1294912970
12950 if (is_ref) {12971 if (is_ref) {
12951 const target = sema.mod.getTarget();12972 const target = sema.mod.getTarget();
12952 const alloc_ty = try Type.ptr(sema.arena, target, .{12973 const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{
12953 .pointee_type = array_ty,12974 .pointee_type = array_ty,
12954 .@"addrspace" = target_util.defaultAddressSpace(target, .local),12975 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
12955 });12976 });
12956 const alloc = try block.addTy(.alloc, alloc_ty);12977 const alloc = try block.addTy(.alloc, alloc_ty);
1295712978
12958 const elem_ptr_ty = try Type.ptr(sema.arena, target, .{12979 const elem_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
12959 .mutable = true,12980 .mutable = true,
12960 .@"addrspace" = target_util.defaultAddressSpace(target, .local),12981 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
12961 .pointee_type = elem_ty,12982 .pointee_type = elem_ty,
...@@ -13017,14 +13038,14 @@ fn zirArrayInitAnon(...@@ -13017,14 +13038,14 @@ fn zirArrayInitAnon(
1301713038
13018 if (is_ref) {13039 if (is_ref) {
13019 const target = sema.mod.getTarget();13040 const target = sema.mod.getTarget();
13020 const alloc_ty = try Type.ptr(sema.arena, target, .{13041 const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{
13021 .pointee_type = tuple_ty,13042 .pointee_type = tuple_ty,
13022 .@"addrspace" = target_util.defaultAddressSpace(target, .local),13043 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
13023 });13044 });
13024 const alloc = try block.addTy(.alloc, alloc_ty);13045 const alloc = try block.addTy(.alloc, alloc_ty);
13025 for (operands) |operand, i_usize| {13046 for (operands) |operand, i_usize| {
13026 const i = @intCast(u32, i_usize);13047 const i = @intCast(u32, i_usize);
13027 const field_ptr_ty = try Type.ptr(sema.arena, target, .{13048 const field_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
13028 .mutable = true,13049 .mutable = true,
13029 .@"addrspace" = target_util.defaultAddressSpace(target, .local),13050 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
13030 .pointee_type = types[i],13051 .pointee_type = types[i],
...@@ -13096,7 +13117,6 @@ fn fieldType(...@@ -13096,7 +13117,6 @@ fn fieldType(
13096 ty_src: LazySrcLoc,13117 ty_src: LazySrcLoc,
13097) CompileError!Air.Inst.Ref {13118) CompileError!Air.Inst.Ref {
13098 const resolved_ty = try sema.resolveTypeFields(block, ty_src, aggregate_ty);13119 const resolved_ty = try sema.resolveTypeFields(block, ty_src, aggregate_ty);
13099 const target = sema.mod.getTarget();
13100 var cur_ty = resolved_ty;13120 var cur_ty = resolved_ty;
13101 while (true) {13121 while (true) {
13102 switch (cur_ty.zigTypeTag()) {13122 switch (cur_ty.zigTypeTag()) {
...@@ -13127,7 +13147,7 @@ fn fieldType(...@@ -13127,7 +13147,7 @@ fn fieldType(
13127 else => {},13147 else => {},
13128 }13148 }
13129 return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{13149 return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{
13130 resolved_ty.fmt(target),13150 resolved_ty.fmt(sema.mod),
13131 });13151 });
13132 }13152 }
13133}13153}
...@@ -13216,10 +13236,10 @@ fn zirUnaryMath(...@@ -13216,10 +13236,10 @@ fn zirUnaryMath(
13216 const scalar_ty = operand_ty.scalarType();13236 const scalar_ty = operand_ty.scalarType();
13217 switch (scalar_ty.zigTypeTag()) {13237 switch (scalar_ty.zigTypeTag()) {
13218 .ComptimeFloat, .Float => {},13238 .ComptimeFloat, .Float => {},
13219 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{scalar_ty.fmt(target)}),13239 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{scalar_ty.fmt(sema.mod)}),
13220 }13240 }
13221 },13241 },
13222 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{operand_ty.fmt(target)}),13242 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{operand_ty.fmt(sema.mod)}),
13223 }13243 }
1322413244
13225 switch (operand_ty.zigTypeTag()) {13245 switch (operand_ty.zigTypeTag()) {
...@@ -13234,7 +13254,7 @@ fn zirUnaryMath(...@@ -13234,7 +13254,7 @@ fn zirUnaryMath(
13234 var elem_buf: Value.ElemValueBuffer = undefined;13254 var elem_buf: Value.ElemValueBuffer = undefined;
13235 const elems = try sema.arena.alloc(Value, vec_len);13255 const elems = try sema.arena.alloc(Value, vec_len);
13236 for (elems) |*elem, i| {13256 for (elems) |*elem, i| {
13237 const elem_val = val.elemValueBuffer(i, &elem_buf);13257 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf);
13238 elem.* = try eval(elem_val, scalar_ty, sema.arena, target);13258 elem.* = try eval(elem_val, scalar_ty, sema.arena, target);
13239 }13259 }
13240 return sema.addConstant(13260 return sema.addConstant(
...@@ -13267,7 +13287,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -13267,7 +13287,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
13267 const src = inst_data.src();13287 const src = inst_data.src();
13268 const operand = sema.resolveInst(inst_data.operand);13288 const operand = sema.resolveInst(inst_data.operand);
13269 const operand_ty = sema.typeOf(operand);13289 const operand_ty = sema.typeOf(operand);
13270 const target = sema.mod.getTarget();13290 const mod = sema.mod;
1327113291
13272 try sema.resolveTypeLayout(block, operand_src, operand_ty);13292 try sema.resolveTypeLayout(block, operand_src, operand_ty);
13273 const enum_ty = switch (operand_ty.zigTypeTag()) {13293 const enum_ty = switch (operand_ty.zigTypeTag()) {
...@@ -13278,31 +13298,33 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -13278,31 +13298,33 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
13278 },13298 },
13279 .Enum => operand_ty,13299 .Enum => operand_ty,
13280 .Union => operand_ty.unionTagType() orelse {13300 .Union => operand_ty.unionTagType() orelse {
13281 const decl = operand_ty.getOwnerDecl();13301 const decl_index = operand_ty.getOwnerDecl();
13302 const decl = mod.declPtr(decl_index);
13282 const msg = msg: {13303 const msg = msg: {
13283 const msg = try sema.errMsg(block, src, "union '{s}' is untagged", .{13304 const msg = try sema.errMsg(block, src, "union '{s}' is untagged", .{
13284 decl.name,13305 decl.name,
13285 });13306 });
13286 errdefer msg.destroy(sema.gpa);13307 errdefer msg.destroy(sema.gpa);
13287 try sema.mod.errNoteNonLazy(decl.srcLoc(), msg, "declared here", .{});13308 try mod.errNoteNonLazy(decl.srcLoc(), msg, "declared here", .{});
13288 break :msg msg;13309 break :msg msg;
13289 };13310 };
13290 return sema.failWithOwnedErrorMsg(block, msg);13311 return sema.failWithOwnedErrorMsg(block, msg);
13291 },13312 },
13292 else => return sema.fail(block, operand_src, "expected enum or union; found {}", .{13313 else => return sema.fail(block, operand_src, "expected enum or union; found {}", .{
13293 operand_ty.fmt(target),13314 operand_ty.fmt(mod),
13294 }),13315 }),
13295 };13316 };
13296 const enum_decl = enum_ty.getOwnerDecl();13317 const enum_decl_index = enum_ty.getOwnerDecl();
13297 const casted_operand = try sema.coerce(block, enum_ty, operand, operand_src);13318 const casted_operand = try sema.coerce(block, enum_ty, operand, operand_src);
13298 if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| {13319 if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| {
13299 const field_index = enum_ty.enumTagFieldIndex(val, target) orelse {13320 const field_index = enum_ty.enumTagFieldIndex(val, mod) orelse {
13321 const enum_decl = mod.declPtr(enum_decl_index);
13300 const msg = msg: {13322 const msg = msg: {
13301 const msg = try sema.errMsg(block, src, "no field with value {} in enum '{s}'", .{13323 const msg = try sema.errMsg(block, src, "no field with value {} in enum '{s}'", .{
13302 casted_operand, enum_decl.name,13324 casted_operand, enum_decl.name,
13303 });13325 });
13304 errdefer msg.destroy(sema.gpa);13326 errdefer msg.destroy(sema.gpa);
13305 try sema.mod.errNoteNonLazy(enum_decl.srcLoc(), msg, "declared here", .{});13327 try mod.errNoteNonLazy(enum_decl.srcLoc(), msg, "declared here", .{});
13306 break :msg msg;13328 break :msg msg;
13307 };13329 };
13308 return sema.failWithOwnedErrorMsg(block, msg);13330 return sema.failWithOwnedErrorMsg(block, msg);
...@@ -13317,6 +13339,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -13317,6 +13339,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
13317}13339}
1331813340
13319fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13341fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13342 const mod = sema.mod;
13320 const inst_data = sema.code.instructions.items(.data)[inst].un_node;13343 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
13321 const src = inst_data.src();13344 const src = inst_data.src();
13322 const type_info_ty = try sema.resolveBuiltinTypeFields(block, src, "Type");13345 const type_info_ty = try sema.resolveBuiltinTypeFields(block, src, "Type");
...@@ -13326,8 +13349,8 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13326,8 +13349,8 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13326 const val = try sema.resolveConstValue(block, operand_src, type_info);13349 const val = try sema.resolveConstValue(block, operand_src, type_info);
13327 const union_val = val.cast(Value.Payload.Union).?.data;13350 const union_val = val.cast(Value.Payload.Union).?.data;
13328 const tag_ty = type_info_ty.unionTagType().?;13351 const tag_ty = type_info_ty.unionTagType().?;
13329 const target = sema.mod.getTarget();13352 const target = mod.getTarget();
13330 const tag_index = tag_ty.enumTagFieldIndex(union_val.tag, target).?;13353 const tag_index = tag_ty.enumTagFieldIndex(union_val.tag, mod).?;
13331 switch (@intToEnum(std.builtin.TypeId, tag_index)) {13354 switch (@intToEnum(std.builtin.TypeId, tag_index)) {
13332 .Type => return Air.Inst.Ref.type_type,13355 .Type => return Air.Inst.Ref.type_type,
13333 .Void => return Air.Inst.Ref.void_type,13356 .Void => return Air.Inst.Ref.void_type,
...@@ -13406,14 +13429,14 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13406,14 +13429,14 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13406 return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});13429 return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});
13407 }13430 }
13408 const sentinel_ptr_val = sentinel_val.castTag(.opt_payload).?.data;13431 const sentinel_ptr_val = sentinel_val.castTag(.opt_payload).?.data;
13409 const ptr_ty = try Type.ptr(sema.arena, target, .{13432 const ptr_ty = try Type.ptr(sema.arena, mod, .{
13410 .@"addrspace" = .generic,13433 .@"addrspace" = .generic,
13411 .pointee_type = child_ty,13434 .pointee_type = child_ty,
13412 });13435 });
13413 actual_sentinel = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;13436 actual_sentinel = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;
13414 }13437 }
1341513438
13416 const ty = try Type.ptr(sema.arena, target, .{13439 const ty = try Type.ptr(sema.arena, mod, .{
13417 .size = ptr_size,13440 .size = ptr_size,
13418 .mutable = !is_const_val.toBool(),13441 .mutable = !is_const_val.toBool(),
13419 .@"volatile" = is_volatile_val.toBool(),13442 .@"volatile" = is_volatile_val.toBool(),
...@@ -13439,14 +13462,14 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13439,14 +13462,14 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13439 var buffer: Value.ToTypeBuffer = undefined;13462 var buffer: Value.ToTypeBuffer = undefined;
13440 const child_ty = try child_val.toType(&buffer).copy(sema.arena);13463 const child_ty = try child_val.toType(&buffer).copy(sema.arena);
13441 const sentinel = if (sentinel_val.castTag(.opt_payload)) |p| blk: {13464 const sentinel = if (sentinel_val.castTag(.opt_payload)) |p| blk: {
13442 const ptr_ty = try Type.ptr(sema.arena, target, .{13465 const ptr_ty = try Type.ptr(sema.arena, mod, .{
13443 .@"addrspace" = .generic,13466 .@"addrspace" = .generic,
13444 .pointee_type = child_ty,13467 .pointee_type = child_ty,
13445 });13468 });
13446 break :blk (try sema.pointerDeref(block, src, p.data, ptr_ty)).?;13469 break :blk (try sema.pointerDeref(block, src, p.data, ptr_ty)).?;
13447 } else null;13470 } else null;
1344813471
13449 const ty = try Type.array(sema.arena, len, sentinel, child_ty, target);13472 const ty = try Type.array(sema.arena, len, sentinel, child_ty, sema.mod);
13450 return sema.addType(ty);13473 return sema.addType(ty);
13451 },13474 },
13452 .Optional => {13475 .Optional => {
...@@ -13483,8 +13506,9 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13483,8 +13506,9 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13483 const payload_val = union_val.val.optionalValue() orelse13506 const payload_val = union_val.val.optionalValue() orelse
13484 return sema.addType(Type.initTag(.anyerror));13507 return sema.addType(Type.initTag(.anyerror));
13485 const slice_val = payload_val.castTag(.slice).?.data;13508 const slice_val = payload_val.castTag(.slice).?.data;
13486 const decl = slice_val.ptr.pointerDecl().?;13509 const decl_index = slice_val.ptr.pointerDecl().?;
13487 try sema.ensureDeclAnalyzed(decl);13510 try sema.ensureDeclAnalyzed(decl_index);
13511 const decl = mod.declPtr(decl_index);
13488 const array_val = decl.val.castTag(.aggregate).?.data;13512 const array_val = decl.val.castTag(.aggregate).?.data;
1348913513
13490 var names: Module.ErrorSet.NameMap = .{};13514 var names: Module.ErrorSet.NameMap = .{};
...@@ -13494,9 +13518,9 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13494,9 +13518,9 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13494 // TODO use reflection instead of magic numbers here13518 // TODO use reflection instead of magic numbers here
13495 // error_set: type,13519 // error_set: type,
13496 const name_val = struct_val[0];13520 const name_val = struct_val[0];
13497 const name_str = try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, target);13521 const name_str = try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, sema.mod);
1349813522
13499 const kv = try sema.mod.getErrorValue(name_str);13523 const kv = try mod.getErrorValue(name_str);
13500 names.putAssumeCapacityNoClobber(kv.key, {});13524 names.putAssumeCapacityNoClobber(kv.key, {});
13501 }13525 }
1350213526
...@@ -13518,7 +13542,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13518,7 +13542,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13518 const is_tuple_val = struct_val[3];13542 const is_tuple_val = struct_val[3];
1351913543
13520 // Decls13544 // Decls
13521 if (decls_val.sliceLen(target) > 0) {13545 if (decls_val.sliceLen(mod) > 0) {
13522 return sema.fail(block, src, "reified structs must have no decls", .{});13546 return sema.fail(block, src, "reified structs must have no decls", .{});
13523 }13547 }
1352413548
...@@ -13548,11 +13572,10 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13548,11 +13572,10 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13548 }13572 }
1354913573
13550 // Decls13574 // Decls
13551 if (decls_val.sliceLen(target) > 0) {13575 if (decls_val.sliceLen(mod) > 0) {
13552 return sema.fail(block, src, "reified enums must have no decls", .{});13576 return sema.fail(block, src, "reified enums must have no decls", .{});
13553 }13577 }
1355413578
13555 const mod = sema.mod;
13556 const gpa = sema.gpa;13579 const gpa = sema.gpa;
13557 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);13580 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
13558 errdefer new_decl_arena.deinit();13581 errdefer new_decl_arena.deinit();
...@@ -13572,20 +13595,20 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13572,20 +13595,20 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13572 };13595 };
13573 const enum_ty = Type.initPayload(&enum_ty_payload.base);13596 const enum_ty = Type.initPayload(&enum_ty_payload.base);
13574 const enum_val = try Value.Tag.ty.create(new_decl_arena_allocator, enum_ty);13597 const enum_val = try Value.Tag.ty.create(new_decl_arena_allocator, enum_ty);
13575 const type_name = try sema.createTypeName(block, .anon, "enum");13598 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
13576 const new_decl = try mod.createAnonymousDeclNamed(block, .{
13577 .ty = Type.type,13599 .ty = Type.type,
13578 .val = enum_val,13600 .val = enum_val,
13579 }, type_name);13601 }, .anon, "enum");
13602 const new_decl = mod.declPtr(new_decl_index);
13580 new_decl.owns_tv = true;13603 new_decl.owns_tv = true;
13581 errdefer mod.abortAnonDecl(new_decl);13604 errdefer mod.abortAnonDecl(new_decl_index);
1358213605
13583 // Enum tag type13606 // Enum tag type
13584 var buffer: Value.ToTypeBuffer = undefined;13607 var buffer: Value.ToTypeBuffer = undefined;
13585 const int_tag_ty = try tag_type_val.toType(&buffer).copy(new_decl_arena_allocator);13608 const int_tag_ty = try tag_type_val.toType(&buffer).copy(new_decl_arena_allocator);
1358613609
13587 enum_obj.* = .{13610 enum_obj.* = .{
13588 .owner_decl = new_decl,13611 .owner_decl = new_decl_index,
13589 .tag_ty = int_tag_ty,13612 .tag_ty = int_tag_ty,
13590 .tag_ty_inferred = false,13613 .tag_ty_inferred = false,
13591 .fields = .{},13614 .fields = .{},
...@@ -13599,17 +13622,17 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13599,17 +13622,17 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13599 };13622 };
1360013623
13601 // Fields13624 // Fields
13602 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));13625 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(mod));
13603 if (fields_len > 0) {13626 if (fields_len > 0) {
13604 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);13627 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
13605 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{13628 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{
13606 .ty = enum_obj.tag_ty,13629 .ty = enum_obj.tag_ty,
13607 .target = target,13630 .mod = mod,
13608 });13631 });
1360913632
13610 var i: usize = 0;13633 var i: usize = 0;
13611 while (i < fields_len) : (i += 1) {13634 while (i < fields_len) : (i += 1) {
13612 const elem_val = try fields_val.elemValue(sema.arena, i);13635 const elem_val = try fields_val.elemValue(sema.mod, sema.arena, i);
13613 const field_struct_val = elem_val.castTag(.aggregate).?.data;13636 const field_struct_val = elem_val.castTag(.aggregate).?.data;
13614 // TODO use reflection instead of magic numbers here13637 // TODO use reflection instead of magic numbers here
13615 // name: []const u813638 // name: []const u8
...@@ -13620,7 +13643,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13620,7 +13643,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13620 const field_name = try name_val.toAllocatedBytes(13643 const field_name = try name_val.toAllocatedBytes(
13621 Type.initTag(.const_slice_u8),13644 Type.initTag(.const_slice_u8),
13622 new_decl_arena_allocator,13645 new_decl_arena_allocator,
13623 target,13646 sema.mod,
13624 );13647 );
1362513648
13626 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);13649 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);
...@@ -13632,13 +13655,13 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13632,13 +13655,13 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13632 const copied_tag_val = try value_val.copy(new_decl_arena_allocator);13655 const copied_tag_val = try value_val.copy(new_decl_arena_allocator);
13633 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{13656 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{
13634 .ty = enum_obj.tag_ty,13657 .ty = enum_obj.tag_ty,
13635 .target = target,13658 .mod = mod,
13636 });13659 });
13637 }13660 }
13638 }13661 }
1363913662
13640 try new_decl.finalizeNewArena(&new_decl_arena);13663 try new_decl.finalizeNewArena(&new_decl_arena);
13641 return sema.analyzeDeclVal(block, src, new_decl);13664 return sema.analyzeDeclVal(block, src, new_decl_index);
13642 },13665 },
13643 .Opaque => {13666 .Opaque => {
13644 const struct_val = union_val.val.castTag(.aggregate).?.data;13667 const struct_val = union_val.val.castTag(.aggregate).?.data;
...@@ -13646,11 +13669,10 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13646,11 +13669,10 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13646 const decls_val = struct_val[0];13669 const decls_val = struct_val[0];
1364713670
13648 // Decls13671 // Decls
13649 if (decls_val.sliceLen(target) > 0) {13672 if (decls_val.sliceLen(mod) > 0) {
13650 return sema.fail(block, src, "reified opaque must have no decls", .{});13673 return sema.fail(block, src, "reified opaque must have no decls", .{});
13651 }13674 }
1365213675
13653 const mod = sema.mod;
13654 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);13676 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);
13655 errdefer new_decl_arena.deinit();13677 errdefer new_decl_arena.deinit();
13656 const new_decl_arena_allocator = new_decl_arena.allocator();13678 const new_decl_arena_allocator = new_decl_arena.allocator();
...@@ -13663,16 +13685,16 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13663,16 +13685,16 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13663 };13685 };
13664 const opaque_ty = Type.initPayload(&opaque_ty_payload.base);13686 const opaque_ty = Type.initPayload(&opaque_ty_payload.base);
13665 const opaque_val = try Value.Tag.ty.create(new_decl_arena_allocator, opaque_ty);13687 const opaque_val = try Value.Tag.ty.create(new_decl_arena_allocator, opaque_ty);
13666 const type_name = try sema.createTypeName(block, .anon, "opaque");13688 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
13667 const new_decl = try mod.createAnonymousDeclNamed(block, .{
13668 .ty = Type.type,13689 .ty = Type.type,
13669 .val = opaque_val,13690 .val = opaque_val,
13670 }, type_name);13691 }, .anon, "opaque");
13692 const new_decl = mod.declPtr(new_decl_index);
13671 new_decl.owns_tv = true;13693 new_decl.owns_tv = true;
13672 errdefer mod.abortAnonDecl(new_decl);13694 errdefer mod.abortAnonDecl(new_decl_index);
1367313695
13674 opaque_obj.* = .{13696 opaque_obj.* = .{
13675 .owner_decl = new_decl,13697 .owner_decl = new_decl_index,
13676 .node_offset = src.node_offset,13698 .node_offset = src.node_offset,
13677 .namespace = .{13699 .namespace = .{
13678 .parent = block.namespace,13700 .parent = block.namespace,
...@@ -13682,7 +13704,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13682,7 +13704,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13682 };13704 };
1368313705
13684 try new_decl.finalizeNewArena(&new_decl_arena);13706 try new_decl.finalizeNewArena(&new_decl_arena);
13685 return sema.analyzeDeclVal(block, src, new_decl);13707 return sema.analyzeDeclVal(block, src, new_decl_index);
13686 },13708 },
13687 .Union => {13709 .Union => {
13688 // TODO use reflection instead of magic numbers here13710 // TODO use reflection instead of magic numbers here
...@@ -13697,7 +13719,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13697,7 +13719,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13697 const decls_val = struct_val[3];13719 const decls_val = struct_val[3];
1369813720
13699 // Decls13721 // Decls
13700 if (decls_val.sliceLen(target) > 0) {13722 if (decls_val.sliceLen(mod) > 0) {
13701 return sema.fail(block, src, "reified unions must have no decls", .{});13723 return sema.fail(block, src, "reified unions must have no decls", .{});
13702 }13724 }
1370313725
...@@ -13714,15 +13736,15 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13714,15 +13736,15 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13714 };13736 };
13715 const union_ty = Type.initPayload(&union_payload.base);13737 const union_ty = Type.initPayload(&union_payload.base);
13716 const new_union_val = try Value.Tag.ty.create(new_decl_arena_allocator, union_ty);13738 const new_union_val = try Value.Tag.ty.create(new_decl_arena_allocator, union_ty);
13717 const type_name = try sema.createTypeName(block, .anon, "union");13739 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
13718 const new_decl = try sema.mod.createAnonymousDeclNamed(block, .{
13719 .ty = Type.type,13740 .ty = Type.type,
13720 .val = new_union_val,13741 .val = new_union_val,
13721 }, type_name);13742 }, .anon, "union");
13743 const new_decl = mod.declPtr(new_decl_index);
13722 new_decl.owns_tv = true;13744 new_decl.owns_tv = true;
13723 errdefer sema.mod.abortAnonDecl(new_decl);13745 errdefer mod.abortAnonDecl(new_decl_index);
13724 union_obj.* = .{13746 union_obj.* = .{
13725 .owner_decl = new_decl,13747 .owner_decl = new_decl_index,
13726 .tag_ty = Type.initTag(.@"null"),13748 .tag_ty = Type.initTag(.@"null"),
13727 .fields = .{},13749 .fields = .{},
13728 .node_offset = src.node_offset,13750 .node_offset = src.node_offset,
...@@ -13737,7 +13759,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13737,7 +13759,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13737 };13759 };
1373813760
13739 // Tag type13761 // Tag type
13740 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));13762 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(mod));
13741 union_obj.tag_ty = if (tag_type_val.optionalValue()) |payload_val| blk: {13763 union_obj.tag_ty = if (tag_type_val.optionalValue()) |payload_val| blk: {
13742 var buffer: Value.ToTypeBuffer = undefined;13764 var buffer: Value.ToTypeBuffer = undefined;
13743 break :blk try payload_val.toType(&buffer).copy(new_decl_arena_allocator);13765 break :blk try payload_val.toType(&buffer).copy(new_decl_arena_allocator);
...@@ -13749,7 +13771,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13749,7 +13771,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1374913771
13750 var i: usize = 0;13772 var i: usize = 0;
13751 while (i < fields_len) : (i += 1) {13773 while (i < fields_len) : (i += 1) {
13752 const elem_val = try fields_val.elemValue(sema.arena, i);13774 const elem_val = try fields_val.elemValue(sema.mod, sema.arena, i);
13753 const field_struct_val = elem_val.castTag(.aggregate).?.data;13775 const field_struct_val = elem_val.castTag(.aggregate).?.data;
13754 // TODO use reflection instead of magic numbers here13776 // TODO use reflection instead of magic numbers here
13755 // name: []const u813777 // name: []const u8
...@@ -13762,7 +13784,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13762,7 +13784,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13762 const field_name = try name_val.toAllocatedBytes(13784 const field_name = try name_val.toAllocatedBytes(
13763 Type.initTag(.const_slice_u8),13785 Type.initTag(.const_slice_u8),
13764 new_decl_arena_allocator,13786 new_decl_arena_allocator,
13765 target,13787 sema.mod,
13766 );13788 );
1376713789
13768 const gop = union_obj.fields.getOrPutAssumeCapacity(field_name);13790 const gop = union_obj.fields.getOrPutAssumeCapacity(field_name);
...@@ -13780,7 +13802,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13780,7 +13802,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13780 }13802 }
1378113803
13782 try new_decl.finalizeNewArena(&new_decl_arena);13804 try new_decl.finalizeNewArena(&new_decl_arena);
13783 return sema.analyzeDeclVal(block, src, new_decl);13805 return sema.analyzeDeclVal(block, src, new_decl_index);
13784 },13806 },
13785 .Fn => return sema.fail(block, src, "TODO: Sema.zirReify for Fn", .{}),13807 .Fn => return sema.fail(block, src, "TODO: Sema.zirReify for Fn", .{}),
13786 .BoundFn => @panic("TODO delete BoundFn from the language"),13808 .BoundFn => @panic("TODO delete BoundFn from the language"),
...@@ -13794,9 +13816,7 @@ fn reifyTuple(...@@ -13794,9 +13816,7 @@ fn reifyTuple(
13794 src: LazySrcLoc,13816 src: LazySrcLoc,
13795 fields_val: Value,13817 fields_val: Value,
13796) CompileError!Air.Inst.Ref {13818) CompileError!Air.Inst.Ref {
13797 const target = sema.mod.getTarget();13819 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(sema.mod));
13798
13799 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));
13800 if (fields_len == 0) return sema.addType(Type.initTag(.empty_struct_literal));13820 if (fields_len == 0) return sema.addType(Type.initTag(.empty_struct_literal));
1380113821
13802 const types = try sema.arena.alloc(Type, fields_len);13822 const types = try sema.arena.alloc(Type, fields_len);
...@@ -13808,7 +13828,7 @@ fn reifyTuple(...@@ -13808,7 +13828,7 @@ fn reifyTuple(
1380813828
13809 var i: usize = 0;13829 var i: usize = 0;
13810 while (i < fields_len) : (i += 1) {13830 while (i < fields_len) : (i += 1) {
13811 const elem_val = try fields_val.elemValue(sema.arena, i);13831 const elem_val = try fields_val.elemValue(sema.mod, sema.arena, i);
13812 const field_struct_val = elem_val.castTag(.aggregate).?.data;13832 const field_struct_val = elem_val.castTag(.aggregate).?.data;
13813 // TODO use reflection instead of magic numbers here13833 // TODO use reflection instead of magic numbers here
13814 // name: []const u813834 // name: []const u8
...@@ -13821,7 +13841,7 @@ fn reifyTuple(...@@ -13821,7 +13841,7 @@ fn reifyTuple(
13821 const field_name = try name_val.toAllocatedBytes(13841 const field_name = try name_val.toAllocatedBytes(
13822 Type.initTag(.const_slice_u8),13842 Type.initTag(.const_slice_u8),
13823 sema.arena,13843 sema.arena,
13824 target,13844 sema.mod,
13825 );13845 );
1382613846
13827 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| {13847 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| {
...@@ -13850,7 +13870,7 @@ fn reifyTuple(...@@ -13850,7 +13870,7 @@ fn reifyTuple(
1385013870
13851 const default_val = if (default_value_val.optionalValue()) |opt_val| blk: {13871 const default_val = if (default_value_val.optionalValue()) |opt_val| blk: {
13852 const payload_val = if (opt_val.pointerDecl()) |opt_decl|13872 const payload_val = if (opt_val.pointerDecl()) |opt_decl|
13853 opt_decl.val13873 sema.mod.declPtr(opt_decl).val
13854 else13874 else
13855 opt_val;13875 opt_val;
13856 break :blk try payload_val.copy(sema.arena);13876 break :blk try payload_val.copy(sema.arena);
...@@ -13883,15 +13903,16 @@ fn reifyStruct(...@@ -13883,15 +13903,16 @@ fn reifyStruct(
13883 const struct_obj = try new_decl_arena_allocator.create(Module.Struct);13903 const struct_obj = try new_decl_arena_allocator.create(Module.Struct);
13884 const struct_ty = try Type.Tag.@"struct".create(new_decl_arena_allocator, struct_obj);13904 const struct_ty = try Type.Tag.@"struct".create(new_decl_arena_allocator, struct_obj);
13885 const new_struct_val = try Value.Tag.ty.create(new_decl_arena_allocator, struct_ty);13905 const new_struct_val = try Value.Tag.ty.create(new_decl_arena_allocator, struct_ty);
13886 const type_name = try sema.createTypeName(block, .anon, "struct");13906 const mod = sema.mod;
13887 const new_decl = try sema.mod.createAnonymousDeclNamed(block, .{13907 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
13888 .ty = Type.type,13908 .ty = Type.type,
13889 .val = new_struct_val,13909 .val = new_struct_val,
13890 }, type_name);13910 }, .anon, "struct");
13911 const new_decl = mod.declPtr(new_decl_index);
13891 new_decl.owns_tv = true;13912 new_decl.owns_tv = true;
13892 errdefer sema.mod.abortAnonDecl(new_decl);13913 errdefer mod.abortAnonDecl(new_decl_index);
13893 struct_obj.* = .{13914 struct_obj.* = .{
13894 .owner_decl = new_decl,13915 .owner_decl = new_decl_index,
13895 .fields = .{},13916 .fields = .{},
13896 .node_offset = src.node_offset,13917 .node_offset = src.node_offset,
13897 .zir_index = inst,13918 .zir_index = inst,
...@@ -13905,14 +13926,14 @@ fn reifyStruct(...@@ -13905,14 +13926,14 @@ fn reifyStruct(
13905 },13926 },
13906 };13927 };
1390713928
13908 const target = sema.mod.getTarget();13929 const target = mod.getTarget();
1390913930
13910 // Fields13931 // Fields
13911 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));13932 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(mod));
13912 try struct_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);13933 try struct_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
13913 var i: usize = 0;13934 var i: usize = 0;
13914 while (i < fields_len) : (i += 1) {13935 while (i < fields_len) : (i += 1) {
13915 const elem_val = try fields_val.elemValue(sema.arena, i);13936 const elem_val = try fields_val.elemValue(sema.mod, sema.arena, i);
13916 const field_struct_val = elem_val.castTag(.aggregate).?.data;13937 const field_struct_val = elem_val.castTag(.aggregate).?.data;
13917 // TODO use reflection instead of magic numbers here13938 // TODO use reflection instead of magic numbers here
13918 // name: []const u813939 // name: []const u8
...@@ -13929,7 +13950,7 @@ fn reifyStruct(...@@ -13929,7 +13950,7 @@ fn reifyStruct(
13929 const field_name = try name_val.toAllocatedBytes(13950 const field_name = try name_val.toAllocatedBytes(
13930 Type.initTag(.const_slice_u8),13951 Type.initTag(.const_slice_u8),
13931 new_decl_arena_allocator,13952 new_decl_arena_allocator,
13932 target,13953 mod,
13933 );13954 );
1393413955
13935 const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);13956 const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);
...@@ -13940,7 +13961,7 @@ fn reifyStruct(...@@ -13940,7 +13961,7 @@ fn reifyStruct(
1394013961
13941 const default_val = if (default_value_val.optionalValue()) |opt_val| blk: {13962 const default_val = if (default_value_val.optionalValue()) |opt_val| blk: {
13942 const payload_val = if (opt_val.pointerDecl()) |opt_decl|13963 const payload_val = if (opt_val.pointerDecl()) |opt_decl|
13943 opt_decl.val13964 mod.declPtr(opt_decl).val
13944 else13965 else
13945 opt_val;13966 opt_val;
13946 break :blk try payload_val.copy(new_decl_arena_allocator);13967 break :blk try payload_val.copy(new_decl_arena_allocator);
...@@ -13957,7 +13978,7 @@ fn reifyStruct(...@@ -13957,7 +13978,7 @@ fn reifyStruct(
13957 }13978 }
1395813979
13959 try new_decl.finalizeNewArena(&new_decl_arena);13980 try new_decl.finalizeNewArena(&new_decl_arena);
13960 return sema.analyzeDeclVal(block, src, new_decl);13981 return sema.analyzeDeclVal(block, src, new_decl_index);
13961}13982}
1396213983
13963fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13984fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -13968,8 +13989,7 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13968,8 +13989,7 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13968 var anon_decl = try block.startAnonDecl(LazySrcLoc.unneeded);13989 var anon_decl = try block.startAnonDecl(LazySrcLoc.unneeded);
13969 defer anon_decl.deinit();13990 defer anon_decl.deinit();
1397013991
13971 const target = sema.mod.getTarget();13992 const bytes = try ty.nameAllocArena(anon_decl.arena(), sema.mod);
13972 const bytes = try ty.nameAllocArena(anon_decl.arena(), target);
1397313993
13974 const new_decl = try anon_decl.finish(13994 const new_decl = try anon_decl.finish(
13975 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),13995 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),
...@@ -14010,7 +14030,7 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -14010,7 +14030,7 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
14010 error.FloatCannotFit => {14030 error.FloatCannotFit => {
14011 return sema.fail(block, operand_src, "integer value {d} cannot be stored in type '{}'", .{14031 return sema.fail(block, operand_src, "integer value {d} cannot be stored in type '{}'", .{
14012 std.math.floor(val.toFloat(f64)),14032 std.math.floor(val.toFloat(f64)),
14013 dest_ty.fmt(target),14033 dest_ty.fmt(sema.mod),
14014 });14034 });
14015 },14035 },
14016 else => |e| return e,14036 else => |e| return e,
...@@ -14064,9 +14084,9 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14064,9 +14084,9 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14064 if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| {14084 if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| {
14065 const addr = val.toUnsignedInt(target);14085 const addr = val.toUnsignedInt(target);
14066 if (!type_res.isAllowzeroPtr() and addr == 0)14086 if (!type_res.isAllowzeroPtr() and addr == 0)
14067 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{type_res.fmt(target)});14087 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{type_res.fmt(sema.mod)});
14068 if (addr != 0 and addr % ptr_align != 0)14088 if (addr != 0 and addr % ptr_align != 0)
14069 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{type_res.fmt(target)});14089 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{type_res.fmt(sema.mod)});
1407014090
14071 const val_payload = try sema.arena.create(Value.Payload.U64);14091 const val_payload = try sema.arena.create(Value.Payload.U64);
14072 val_payload.* = .{14092 val_payload.* = .{
...@@ -14110,7 +14130,6 @@ fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -14110,7 +14130,6 @@ fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
14110 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);14130 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
14111 const operand = sema.resolveInst(extra.rhs);14131 const operand = sema.resolveInst(extra.rhs);
14112 const operand_ty = sema.typeOf(operand);14132 const operand_ty = sema.typeOf(operand);
14113 const target = sema.mod.getTarget();
14114 try sema.checkErrorSetType(block, dest_ty_src, dest_ty);14133 try sema.checkErrorSetType(block, dest_ty_src, dest_ty);
14115 try sema.checkErrorSetType(block, operand_src, operand_ty);14134 try sema.checkErrorSetType(block, operand_src, operand_ty);
1411614135
...@@ -14124,7 +14143,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -14124,7 +14143,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
14124 block,14143 block,
14125 src,14144 src,
14126 "error.{s} not a member of error set '{}'",14145 "error.{s} not a member of error set '{}'",
14127 .{ error_name, dest_ty.fmt(target) },14146 .{ error_name, dest_ty.fmt(sema.mod) },
14128 );14147 );
14129 }14148 }
14130 }14149 }
...@@ -14178,11 +14197,11 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -14178,11 +14197,11 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
14178 var buf: Type.Payload.ElemType = undefined;14197 var buf: Type.Payload.ElemType = undefined;
14179 var dest_ptr_info = dest_ty.optionalChild(&buf).ptrInfo().data;14198 var dest_ptr_info = dest_ty.optionalChild(&buf).ptrInfo().data;
14180 dest_ptr_info.@"align" = operand_align;14199 dest_ptr_info.@"align" = operand_align;
14181 break :blk try Type.optional(sema.arena, try Type.ptr(sema.arena, target, dest_ptr_info));14200 break :blk try Type.optional(sema.arena, try Type.ptr(sema.arena, sema.mod, dest_ptr_info));
14182 } else {14201 } else {
14183 var dest_ptr_info = dest_ty.ptrInfo().data;14202 var dest_ptr_info = dest_ty.ptrInfo().data;
14184 dest_ptr_info.@"align" = operand_align;14203 dest_ptr_info.@"align" = operand_align;
14185 break :blk try Type.ptr(sema.arena, target, dest_ptr_info);14204 break :blk try Type.ptr(sema.arena, sema.mod, dest_ptr_info);
14186 }14205 }
14187 };14206 };
1418814207
...@@ -14235,7 +14254,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14235,7 +14254,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1423514254
14236 if (operand_info.signedness != dest_info.signedness) {14255 if (operand_info.signedness != dest_info.signedness) {
14237 return sema.fail(block, operand_src, "expected {s} integer type, found '{}'", .{14256 return sema.fail(block, operand_src, "expected {s} integer type, found '{}'", .{
14238 @tagName(dest_info.signedness), operand_ty.fmt(target),14257 @tagName(dest_info.signedness), operand_ty.fmt(sema.mod),
14239 });14258 });
14240 }14259 }
14241 if (operand_info.bits < dest_info.bits) {14260 if (operand_info.bits < dest_info.bits) {
...@@ -14244,7 +14263,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14244,7 +14263,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14244 block,14263 block,
14245 src,14264 src,
14246 "destination type '{}' has more bits than source type '{}'",14265 "destination type '{}' has more bits than source type '{}'",
14247 .{ dest_ty.fmt(target), operand_ty.fmt(target) },14266 .{ dest_ty.fmt(sema.mod), operand_ty.fmt(sema.mod) },
14248 );14267 );
14249 errdefer msg.destroy(sema.gpa);14268 errdefer msg.destroy(sema.gpa);
14250 try sema.errNote(block, dest_ty_src, msg, "destination type has {d} bits", .{14269 try sema.errNote(block, dest_ty_src, msg, "destination type has {d} bits", .{
...@@ -14270,7 +14289,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14270,7 +14289,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14270 var elem_buf: Value.ElemValueBuffer = undefined;14289 var elem_buf: Value.ElemValueBuffer = undefined;
14271 const elems = try sema.arena.alloc(Value, operand_ty.vectorLen());14290 const elems = try sema.arena.alloc(Value, operand_ty.vectorLen());
14272 for (elems) |*elem, i| {14291 for (elems) |*elem, i| {
14273 const elem_val = val.elemValueBuffer(i, &elem_buf);14292 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf);
14274 elem.* = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, target);14293 elem.* = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, target);
14275 }14294 }
14276 return sema.addConstant(14295 return sema.addConstant(
...@@ -14302,8 +14321,7 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -14302,8 +14321,7 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
14302 // TODO insert safety check that the alignment is correct14321 // TODO insert safety check that the alignment is correct
1430314322
14304 const ptr_info = ptr_ty.ptrInfo().data;14323 const ptr_info = ptr_ty.ptrInfo().data;
14305 const target = sema.mod.getTarget();14324 const dest_ty = try Type.ptr(sema.arena, sema.mod, .{
14306 const dest_ty = try Type.ptr(sema.arena, target, .{
14307 .pointee_type = ptr_info.pointee_type,14325 .pointee_type = ptr_info.pointee_type,
14308 .@"align" = dest_align,14326 .@"align" = dest_align,
14309 .@"addrspace" = ptr_info.@"addrspace",14327 .@"addrspace" = ptr_info.@"addrspace",
...@@ -14346,7 +14364,7 @@ fn zirBitCount(...@@ -14346,7 +14364,7 @@ fn zirBitCount(
14346 const elems = try sema.arena.alloc(Value, vec_len);14364 const elems = try sema.arena.alloc(Value, vec_len);
14347 const scalar_ty = operand_ty.scalarType();14365 const scalar_ty = operand_ty.scalarType();
14348 for (elems) |*elem, i| {14366 for (elems) |*elem, i| {
14349 const elem_val = val.elemValueBuffer(i, &elem_buf);14367 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf);
14350 const count = comptimeOp(elem_val, scalar_ty, target);14368 const count = comptimeOp(elem_val, scalar_ty, target);
14351 elem.* = try Value.Tag.int_u64.create(sema.arena, count);14369 elem.* = try Value.Tag.int_u64.create(sema.arena, count);
14352 }14370 }
...@@ -14386,7 +14404,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14386,7 +14404,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14386 block,14404 block,
14387 ty_src,14405 ty_src,
14388 "@byteSwap requires the number of bits to be evenly divisible by 8, but {} has {} bits",14406 "@byteSwap requires the number of bits to be evenly divisible by 8, but {} has {} bits",
14389 .{ scalar_ty.fmt(target), bits },14407 .{ scalar_ty.fmt(sema.mod), bits },
14390 );14408 );
14391 }14409 }
1439214410
...@@ -14414,7 +14432,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14414,7 +14432,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14414 var elem_buf: Value.ElemValueBuffer = undefined;14432 var elem_buf: Value.ElemValueBuffer = undefined;
14415 const elems = try sema.arena.alloc(Value, vec_len);14433 const elems = try sema.arena.alloc(Value, vec_len);
14416 for (elems) |*elem, i| {14434 for (elems) |*elem, i| {
14417 const elem_val = val.elemValueBuffer(i, &elem_buf);14435 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf);
14418 elem.* = try elem_val.byteSwap(operand_ty, target, sema.arena);14436 elem.* = try elem_val.byteSwap(operand_ty, target, sema.arena);
14419 }14437 }
14420 return sema.addConstant(14438 return sema.addConstant(
...@@ -14462,7 +14480,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -14462,7 +14480,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
14462 var elem_buf: Value.ElemValueBuffer = undefined;14480 var elem_buf: Value.ElemValueBuffer = undefined;
14463 const elems = try sema.arena.alloc(Value, vec_len);14481 const elems = try sema.arena.alloc(Value, vec_len);
14464 for (elems) |*elem, i| {14482 for (elems) |*elem, i| {
14465 const elem_val = val.elemValueBuffer(i, &elem_buf);14483 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf);
14466 elem.* = try elem_val.bitReverse(operand_ty, target, sema.arena);14484 elem.* = try elem_val.bitReverse(operand_ty, target, sema.arena);
14467 }14485 }
14468 return sema.addConstant(14486 return sema.addConstant(
...@@ -14506,7 +14524,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -14506,7 +14524,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
14506 block,14524 block,
14507 lhs_src,14525 lhs_src,
14508 "expected struct type, found '{}'",14526 "expected struct type, found '{}'",
14509 .{ty.fmt(target)},14527 .{ty.fmt(sema.mod)},
14510 );14528 );
14511 }14529 }
1451214530
...@@ -14516,7 +14534,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -14516,7 +14534,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
14516 block,14534 block,
14517 rhs_src,14535 rhs_src,
14518 "struct '{}' has no field '{s}'",14536 "struct '{}' has no field '{s}'",
14519 .{ ty.fmt(target), field_name },14537 .{ ty.fmt(sema.mod), field_name },
14520 );14538 );
14521 };14539 };
1452214540
...@@ -14542,20 +14560,18 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -14542,20 +14560,18 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
14542}14560}
1454314561
14544fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {14562fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
14545 const target = sema.mod.getTarget();
14546 switch (ty.zigTypeTag()) {14563 switch (ty.zigTypeTag()) {
14547 .Struct, .Enum, .Union, .Opaque => return,14564 .Struct, .Enum, .Union, .Opaque => return,
14548 else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty.fmt(target)}),14565 else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty.fmt(sema.mod)}),
14549 }14566 }
14550}14567}
1455114568
14552/// Returns `true` if the type was a comptime_int.14569/// Returns `true` if the type was a comptime_int.
14553fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {14570fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {
14554 const target = sema.mod.getTarget();
14555 switch (try ty.zigTypeTagOrPoison()) {14571 switch (try ty.zigTypeTagOrPoison()) {
14556 .ComptimeInt => return true,14572 .ComptimeInt => return true,
14557 .Int => return false,14573 .Int => return false,
14558 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty.fmt(target)}),14574 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty.fmt(sema.mod)}),
14559 }14575 }
14560}14576}
1456114577
...@@ -14565,7 +14581,6 @@ fn checkPtrOperand(...@@ -14565,7 +14581,6 @@ fn checkPtrOperand(
14565 ty_src: LazySrcLoc,14581 ty_src: LazySrcLoc,
14566 ty: Type,14582 ty: Type,
14567) CompileError!void {14583) CompileError!void {
14568 const target = sema.mod.getTarget();
14569 switch (ty.zigTypeTag()) {14584 switch (ty.zigTypeTag()) {
14570 .Pointer => return,14585 .Pointer => return,
14571 .Fn => {14586 .Fn => {
...@@ -14574,7 +14589,7 @@ fn checkPtrOperand(...@@ -14574,7 +14589,7 @@ fn checkPtrOperand(
14574 block,14589 block,
14575 ty_src,14590 ty_src,
14576 "expected pointer, found {}",14591 "expected pointer, found {}",
14577 .{ty.fmt(target)},14592 .{ty.fmt(sema.mod)},
14578 );14593 );
14579 errdefer msg.destroy(sema.gpa);14594 errdefer msg.destroy(sema.gpa);
1458014595
...@@ -14587,7 +14602,7 @@ fn checkPtrOperand(...@@ -14587,7 +14602,7 @@ fn checkPtrOperand(
14587 .Optional => if (ty.isPtrLikeOptional()) return,14602 .Optional => if (ty.isPtrLikeOptional()) return,
14588 else => {},14603 else => {},
14589 }14604 }
14590 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(target)});14605 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(sema.mod)});
14591}14606}
1459214607
14593fn checkPtrType(14608fn checkPtrType(
...@@ -14596,7 +14611,6 @@ fn checkPtrType(...@@ -14596,7 +14611,6 @@ fn checkPtrType(
14596 ty_src: LazySrcLoc,14611 ty_src: LazySrcLoc,
14597 ty: Type,14612 ty: Type,
14598) CompileError!void {14613) CompileError!void {
14599 const target = sema.mod.getTarget();
14600 switch (ty.zigTypeTag()) {14614 switch (ty.zigTypeTag()) {
14601 .Pointer => return,14615 .Pointer => return,
14602 .Fn => {14616 .Fn => {
...@@ -14605,7 +14619,7 @@ fn checkPtrType(...@@ -14605,7 +14619,7 @@ fn checkPtrType(
14605 block,14619 block,
14606 ty_src,14620 ty_src,
14607 "expected pointer type, found '{}'",14621 "expected pointer type, found '{}'",
14608 .{ty.fmt(target)},14622 .{ty.fmt(sema.mod)},
14609 );14623 );
14610 errdefer msg.destroy(sema.gpa);14624 errdefer msg.destroy(sema.gpa);
1461114625
...@@ -14618,7 +14632,7 @@ fn checkPtrType(...@@ -14618,7 +14632,7 @@ fn checkPtrType(
14618 .Optional => if (ty.isPtrLikeOptional()) return,14632 .Optional => if (ty.isPtrLikeOptional()) return,
14619 else => {},14633 else => {},
14620 }14634 }
14621 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(target)});14635 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(sema.mod)});
14622}14636}
1462314637
14624fn checkVectorElemType(14638fn checkVectorElemType(
...@@ -14631,8 +14645,7 @@ fn checkVectorElemType(...@@ -14631,8 +14645,7 @@ fn checkVectorElemType(
14631 .Int, .Float, .Bool => return,14645 .Int, .Float, .Bool => return,
14632 else => if (ty.isPtrAtRuntime()) return,14646 else => if (ty.isPtrAtRuntime()) return,
14633 }14647 }
14634 const target = sema.mod.getTarget();14648 return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty.fmt(sema.mod)});
14635 return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty.fmt(target)});
14636}14649}
1463714650
14638fn checkFloatType(14651fn checkFloatType(
...@@ -14641,10 +14654,9 @@ fn checkFloatType(...@@ -14641,10 +14654,9 @@ fn checkFloatType(
14641 ty_src: LazySrcLoc,14654 ty_src: LazySrcLoc,
14642 ty: Type,14655 ty: Type,
14643) CompileError!void {14656) CompileError!void {
14644 const target = sema.mod.getTarget();
14645 switch (ty.zigTypeTag()) {14657 switch (ty.zigTypeTag()) {
14646 .ComptimeInt, .ComptimeFloat, .Float => {},14658 .ComptimeInt, .ComptimeFloat, .Float => {},
14647 else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty.fmt(target)}),14659 else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty.fmt(sema.mod)}),
14648 }14660 }
14649}14661}
1465014662
...@@ -14654,14 +14666,13 @@ fn checkNumericType(...@@ -14654,14 +14666,13 @@ fn checkNumericType(
14654 ty_src: LazySrcLoc,14666 ty_src: LazySrcLoc,
14655 ty: Type,14667 ty: Type,
14656) CompileError!void {14668) CompileError!void {
14657 const target = sema.mod.getTarget();
14658 switch (ty.zigTypeTag()) {14669 switch (ty.zigTypeTag()) {
14659 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},14670 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},
14660 .Vector => switch (ty.childType().zigTypeTag()) {14671 .Vector => switch (ty.childType().zigTypeTag()) {
14661 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},14672 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},
14662 else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}),14673 else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}),
14663 },14674 },
14664 else => return sema.fail(block, ty_src, "expected number, found '{}'", .{ty.fmt(target)}),14675 else => return sema.fail(block, ty_src, "expected number, found '{}'", .{ty.fmt(sema.mod)}),
14665 }14676 }
14666}14677}
1466714678
...@@ -14697,7 +14708,7 @@ fn checkAtomicOperandType(...@@ -14697,7 +14708,7 @@ fn checkAtomicOperandType(
14697 block,14708 block,
14698 ty_src,14709 ty_src,
14699 "expected bool, integer, float, enum, or pointer type; found {}",14710 "expected bool, integer, float, enum, or pointer type; found {}",
14700 .{ty.fmt(target)},14711 .{ty.fmt(sema.mod)},
14701 );14712 );
14702 },14713 },
14703 };14714 };
...@@ -14761,7 +14772,6 @@ fn checkIntOrVector(...@@ -14761,7 +14772,6 @@ fn checkIntOrVector(
14761 operand_src: LazySrcLoc,14772 operand_src: LazySrcLoc,
14762) CompileError!Type {14773) CompileError!Type {
14763 const operand_ty = sema.typeOf(operand);14774 const operand_ty = sema.typeOf(operand);
14764 const target = sema.mod.getTarget();
14765 switch (try operand_ty.zigTypeTagOrPoison()) {14775 switch (try operand_ty.zigTypeTagOrPoison()) {
14766 .Int => return operand_ty,14776 .Int => return operand_ty,
14767 .Vector => {14777 .Vector => {
...@@ -14769,12 +14779,12 @@ fn checkIntOrVector(...@@ -14769,12 +14779,12 @@ fn checkIntOrVector(
14769 switch (try elem_ty.zigTypeTagOrPoison()) {14779 switch (try elem_ty.zigTypeTagOrPoison()) {
14770 .Int => return elem_ty,14780 .Int => return elem_ty,
14771 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{14781 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
14772 elem_ty.fmt(target),14782 elem_ty.fmt(sema.mod),
14773 }),14783 }),
14774 }14784 }
14775 },14785 },
14776 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{14786 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{
14777 operand_ty.fmt(target),14787 operand_ty.fmt(sema.mod),
14778 }),14788 }),
14779 }14789 }
14780}14790}
...@@ -14786,7 +14796,6 @@ fn checkIntOrVectorAllowComptime(...@@ -14786,7 +14796,6 @@ fn checkIntOrVectorAllowComptime(
14786 operand_src: LazySrcLoc,14796 operand_src: LazySrcLoc,
14787) CompileError!Type {14797) CompileError!Type {
14788 const operand_ty = sema.typeOf(operand);14798 const operand_ty = sema.typeOf(operand);
14789 const target = sema.mod.getTarget();
14790 switch (try operand_ty.zigTypeTagOrPoison()) {14799 switch (try operand_ty.zigTypeTagOrPoison()) {
14791 .Int, .ComptimeInt => return operand_ty,14800 .Int, .ComptimeInt => return operand_ty,
14792 .Vector => {14801 .Vector => {
...@@ -14794,21 +14803,20 @@ fn checkIntOrVectorAllowComptime(...@@ -14794,21 +14803,20 @@ fn checkIntOrVectorAllowComptime(
14794 switch (try elem_ty.zigTypeTagOrPoison()) {14803 switch (try elem_ty.zigTypeTagOrPoison()) {
14795 .Int, .ComptimeInt => return elem_ty,14804 .Int, .ComptimeInt => return elem_ty,
14796 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{14805 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
14797 elem_ty.fmt(target),14806 elem_ty.fmt(sema.mod),
14798 }),14807 }),
14799 }14808 }
14800 },14809 },
14801 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{14810 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{
14802 operand_ty.fmt(target),14811 operand_ty.fmt(sema.mod),
14803 }),14812 }),
14804 }14813 }
14805}14814}
1480614815
14807fn checkErrorSetType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {14816fn checkErrorSetType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
14808 const target = sema.mod.getTarget();
14809 switch (ty.zigTypeTag()) {14817 switch (ty.zigTypeTag()) {
14810 .ErrorSet => return,14818 .ErrorSet => return,
14811 else => return sema.fail(block, src, "expected error set type, found '{}'", .{ty.fmt(target)}),14819 else => return sema.fail(block, src, "expected error set type, found '{}'", .{ty.fmt(sema.mod)}),
14812 }14820 }
14813}14821}
1481414822
...@@ -14892,10 +14900,9 @@ fn checkVectorizableBinaryOperands(...@@ -14892,10 +14900,9 @@ fn checkVectorizableBinaryOperands(
14892 return sema.failWithOwnedErrorMsg(block, msg);14900 return sema.failWithOwnedErrorMsg(block, msg);
14893 }14901 }
14894 } else {14902 } else {
14895 const target = sema.mod.getTarget();
14896 const msg = msg: {14903 const msg = msg: {
14897 const msg = try sema.errMsg(block, src, "mixed scalar and vector operands: {} and {}", .{14904 const msg = try sema.errMsg(block, src, "mixed scalar and vector operands: {} and {}", .{
14898 lhs_ty.fmt(target), rhs_ty.fmt(target),14905 lhs_ty.fmt(sema.mod), rhs_ty.fmt(sema.mod),
14899 });14906 });
14900 errdefer msg.destroy(sema.gpa);14907 errdefer msg.destroy(sema.gpa);
14901 if (lhs_is_vector) {14908 if (lhs_is_vector) {
...@@ -14934,9 +14941,8 @@ fn resolveExportOptions(...@@ -14934,9 +14941,8 @@ fn resolveExportOptions(
14934 return sema.fail(block, src, "TODO: implement exporting with linksection", .{});14941 return sema.fail(block, src, "TODO: implement exporting with linksection", .{});
14935 }14942 }
14936 const name_ty = Type.initTag(.const_slice_u8);14943 const name_ty = Type.initTag(.const_slice_u8);
14937 const target = sema.mod.getTarget();
14938 return std.builtin.ExportOptions{14944 return std.builtin.ExportOptions{
14939 .name = try name_val.toAllocatedBytes(name_ty, sema.arena, target),14945 .name = try name_val.toAllocatedBytes(name_ty, sema.arena, sema.mod),
14940 .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage),14946 .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage),
14941 .section = null, // TODO14947 .section = null, // TODO
14942 };14948 };
...@@ -14995,13 +15001,12 @@ fn zirCmpxchg(...@@ -14995,13 +15001,12 @@ fn zirCmpxchg(
14995 const ptr_ty = sema.typeOf(ptr);15001 const ptr_ty = sema.typeOf(ptr);
14996 const elem_ty = ptr_ty.elemType();15002 const elem_ty = ptr_ty.elemType();
14997 try sema.checkAtomicOperandType(block, elem_ty_src, elem_ty);15003 try sema.checkAtomicOperandType(block, elem_ty_src, elem_ty);
14998 const target = sema.mod.getTarget();
14999 if (elem_ty.zigTypeTag() == .Float) {15004 if (elem_ty.zigTypeTag() == .Float) {
15000 return sema.fail(15005 return sema.fail(
15001 block,15006 block,
15002 elem_ty_src,15007 elem_ty_src,
15003 "expected bool, integer, enum, or pointer type; found '{}'",15008 "expected bool, integer, enum, or pointer type; found '{}'",
15004 .{elem_ty.fmt(target)},15009 .{elem_ty.fmt(sema.mod)},
15005 );15010 );
15006 }15011 }
15007 const expected_value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.expected_value), expected_src);15012 const expected_value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.expected_value), expected_src);
...@@ -15038,7 +15043,7 @@ fn zirCmpxchg(...@@ -15038,7 +15043,7 @@ fn zirCmpxchg(
15038 return sema.addConstUndef(result_ty);15043 return sema.addConstUndef(result_ty);
15039 }15044 }
15040 const stored_val = (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) orelse break :rs ptr_src;15045 const stored_val = (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) orelse break :rs ptr_src;
15041 const result_val = if (stored_val.eql(expected_val, elem_ty, target)) blk: {15046 const result_val = if (stored_val.eql(expected_val, elem_ty, sema.mod)) blk: {
15042 try sema.storePtr(block, src, ptr, new_value);15047 try sema.storePtr(block, src, ptr, new_value);
15043 break :blk Value.@"null";15048 break :blk Value.@"null";
15044 } else try Value.Tag.opt_payload.create(sema.arena, stored_val);15049 } else try Value.Tag.opt_payload.create(sema.arena, stored_val);
...@@ -15103,7 +15108,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -15103,7 +15108,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
15103 const target = sema.mod.getTarget();15108 const target = sema.mod.getTarget();
1510415109
15105 if (operand_ty.zigTypeTag() != .Vector) {15110 if (operand_ty.zigTypeTag() != .Vector) {
15106 return sema.fail(block, operand_src, "expected vector, found {}", .{operand_ty.fmt(target)});15111 return sema.fail(block, operand_src, "expected vector, found {}", .{operand_ty.fmt(sema.mod)});
15107 }15112 }
1510815113
15109 const scalar_ty = operand_ty.childType();15114 const scalar_ty = operand_ty.childType();
...@@ -15113,13 +15118,13 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -15113,13 +15118,13 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
15113 .And, .Or, .Xor => switch (scalar_ty.zigTypeTag()) {15118 .And, .Or, .Xor => switch (scalar_ty.zigTypeTag()) {
15114 .Int, .Bool => {},15119 .Int, .Bool => {},
15115 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or boolean operand; found {}", .{15120 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or boolean operand; found {}", .{
15116 @tagName(operation), operand_ty.fmt(target),15121 @tagName(operation), operand_ty.fmt(sema.mod),
15117 }),15122 }),
15118 },15123 },
15119 .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag()) {15124 .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag()) {
15120 .Int, .Float => {},15125 .Int, .Float => {},
15121 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or float operand; found {}", .{15126 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or float operand; found {}", .{
15122 @tagName(operation), operand_ty.fmt(target),15127 @tagName(operation), operand_ty.fmt(sema.mod),
15123 }),15128 }),
15124 },15129 },
15125 }15130 }
...@@ -15134,11 +15139,11 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -15134,11 +15139,11 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
15134 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |operand_val| {15139 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |operand_val| {
15135 if (operand_val.isUndef()) return sema.addConstUndef(scalar_ty);15140 if (operand_val.isUndef()) return sema.addConstUndef(scalar_ty);
1513615141
15137 var accum: Value = try operand_val.elemValue(sema.arena, 0);15142 var accum: Value = try operand_val.elemValue(sema.mod, sema.arena, 0);
15138 var elem_buf: Value.ElemValueBuffer = undefined;15143 var elem_buf: Value.ElemValueBuffer = undefined;
15139 var i: u32 = 1;15144 var i: u32 = 1;
15140 while (i < vec_len) : (i += 1) {15145 while (i < vec_len) : (i += 1) {
15141 const elem_val = operand_val.elemValueBuffer(i, &elem_buf);15146 const elem_val = operand_val.elemValueBuffer(sema.mod, i, &elem_buf);
15142 switch (operation) {15147 switch (operation) {
15143 .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena, target),15148 .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena, target),
15144 .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena, target),15149 .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena, target),
...@@ -15174,11 +15179,10 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -15174,11 +15179,10 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
15174 var b = sema.resolveInst(extra.b);15179 var b = sema.resolveInst(extra.b);
15175 var mask = sema.resolveInst(extra.mask);15180 var mask = sema.resolveInst(extra.mask);
15176 var mask_ty = sema.typeOf(mask);15181 var mask_ty = sema.typeOf(mask);
15177 const target = sema.mod.getTarget();
1517815182
15179 const mask_len = switch (sema.typeOf(mask).zigTypeTag()) {15183 const mask_len = switch (sema.typeOf(mask).zigTypeTag()) {
15180 .Array, .Vector => sema.typeOf(mask).arrayLen(),15184 .Array, .Vector => sema.typeOf(mask).arrayLen(),
15181 else => return sema.fail(block, mask_src, "expected vector or array, found {}", .{sema.typeOf(mask).fmt(target)}),15185 else => return sema.fail(block, mask_src, "expected vector or array, found {}", .{sema.typeOf(mask).fmt(sema.mod)}),
15182 };15186 };
15183 mask_ty = try Type.Tag.vector.create(sema.arena, .{15187 mask_ty = try Type.Tag.vector.create(sema.arena, .{
15184 .len = mask_len,15188 .len = mask_len,
...@@ -15210,21 +15214,20 @@ fn analyzeShuffle(...@@ -15210,21 +15214,20 @@ fn analyzeShuffle(
15210 .elem_type = elem_ty,15214 .elem_type = elem_ty,
15211 });15215 });
1521215216
15213 const target = sema.mod.getTarget();
15214 var maybe_a_len = switch (sema.typeOf(a).zigTypeTag()) {15217 var maybe_a_len = switch (sema.typeOf(a).zigTypeTag()) {
15215 .Array, .Vector => sema.typeOf(a).arrayLen(),15218 .Array, .Vector => sema.typeOf(a).arrayLen(),
15216 .Undefined => null,15219 .Undefined => null,
15217 else => return sema.fail(block, a_src, "expected vector or array with element type {}, found {}", .{15220 else => return sema.fail(block, a_src, "expected vector or array with element type {}, found {}", .{
15218 elem_ty.fmt(target),15221 elem_ty.fmt(sema.mod),
15219 sema.typeOf(a).fmt(target),15222 sema.typeOf(a).fmt(sema.mod),
15220 }),15223 }),
15221 };15224 };
15222 var maybe_b_len = switch (sema.typeOf(b).zigTypeTag()) {15225 var maybe_b_len = switch (sema.typeOf(b).zigTypeTag()) {
15223 .Array, .Vector => sema.typeOf(b).arrayLen(),15226 .Array, .Vector => sema.typeOf(b).arrayLen(),
15224 .Undefined => null,15227 .Undefined => null,
15225 else => return sema.fail(block, b_src, "expected vector or array with element type {}, found {}", .{15228 else => return sema.fail(block, b_src, "expected vector or array with element type {}, found {}", .{
15226 elem_ty.fmt(target),15229 elem_ty.fmt(sema.mod),
15227 sema.typeOf(b).fmt(target),15230 sema.typeOf(b).fmt(sema.mod),
15228 }),15231 }),
15229 };15232 };
15230 if (maybe_a_len == null and maybe_b_len == null) {15233 if (maybe_a_len == null and maybe_b_len == null) {
...@@ -15253,7 +15256,7 @@ fn analyzeShuffle(...@@ -15253,7 +15256,7 @@ fn analyzeShuffle(
15253 var i: usize = 0;15256 var i: usize = 0;
15254 while (i < mask_len) : (i += 1) {15257 while (i < mask_len) : (i += 1) {
15255 var buf: Value.ElemValueBuffer = undefined;15258 var buf: Value.ElemValueBuffer = undefined;
15256 const elem = mask.elemValueBuffer(i, &buf);15259 const elem = mask.elemValueBuffer(sema.mod, i, &buf);
15257 if (elem.isUndef()) continue;15260 if (elem.isUndef()) continue;
15258 const int = elem.toSignedInt();15261 const int = elem.toSignedInt();
15259 var unsigned: u32 = undefined;15262 var unsigned: u32 = undefined;
...@@ -15272,7 +15275,7 @@ fn analyzeShuffle(...@@ -15272,7 +15275,7 @@ fn analyzeShuffle(
1527215275
15273 try sema.errNote(block, operand_info[chosen][1], msg, "selected index {d} out of bounds of {}", .{15276 try sema.errNote(block, operand_info[chosen][1], msg, "selected index {d} out of bounds of {}", .{
15274 unsigned,15277 unsigned,
15275 operand_info[chosen][2].fmt(target),15278 operand_info[chosen][2].fmt(sema.mod),
15276 });15279 });
1527715280
15278 if (chosen == 1) {15281 if (chosen == 1) {
...@@ -15292,7 +15295,7 @@ fn analyzeShuffle(...@@ -15292,7 +15295,7 @@ fn analyzeShuffle(
15292 i = 0;15295 i = 0;
15293 while (i < mask_len) : (i += 1) {15296 while (i < mask_len) : (i += 1) {
15294 var buf: Value.ElemValueBuffer = undefined;15297 var buf: Value.ElemValueBuffer = undefined;
15295 const mask_elem_val = mask.elemValueBuffer(i, &buf);15298 const mask_elem_val = mask.elemValueBuffer(sema.mod, i, &buf);
15296 if (mask_elem_val.isUndef()) {15299 if (mask_elem_val.isUndef()) {
15297 values[i] = Value.undef;15300 values[i] = Value.undef;
15298 continue;15301 continue;
...@@ -15300,9 +15303,9 @@ fn analyzeShuffle(...@@ -15300,9 +15303,9 @@ fn analyzeShuffle(
15300 const int = mask_elem_val.toSignedInt();15303 const int = mask_elem_val.toSignedInt();
15301 const unsigned = if (int >= 0) @intCast(u32, int) else @intCast(u32, ~int);15304 const unsigned = if (int >= 0) @intCast(u32, int) else @intCast(u32, ~int);
15302 if (int >= 0) {15305 if (int >= 0) {
15303 values[i] = try a_val.elemValue(sema.arena, unsigned);15306 values[i] = try a_val.elemValue(sema.mod, sema.arena, unsigned);
15304 } else {15307 } else {
15305 values[i] = try b_val.elemValue(sema.arena, unsigned);15308 values[i] = try b_val.elemValue(sema.mod, sema.arena, unsigned);
15306 }15309 }
15307 }15310 }
15308 const res_val = try Value.Tag.aggregate.create(sema.arena, values);15311 const res_val = try Value.Tag.aggregate.create(sema.arena, values);
...@@ -15358,7 +15361,6 @@ fn analyzeShuffle(...@@ -15358,7 +15361,6 @@ fn analyzeShuffle(
15358fn zirSelect(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15361fn zirSelect(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15359 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;15362 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
15360 const extra = sema.code.extraData(Zir.Inst.Select, inst_data.payload_index).data;15363 const extra = sema.code.extraData(Zir.Inst.Select, inst_data.payload_index).data;
15361 const target = sema.mod.getTarget();
1536215364
15363 const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };15365 const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
15364 const pred_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };15366 const pred_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
...@@ -15372,7 +15374,7 @@ fn zirSelect(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -15372,7 +15374,7 @@ fn zirSelect(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1537215374
15373 const vec_len_u64 = switch (try pred_ty.zigTypeTagOrPoison()) {15375 const vec_len_u64 = switch (try pred_ty.zigTypeTagOrPoison()) {
15374 .Vector, .Array => pred_ty.arrayLen(),15376 .Vector, .Array => pred_ty.arrayLen(),
15375 else => return sema.fail(block, pred_src, "expected vector or array, found '{}'", .{pred_ty.fmt(target)}),15377 else => return sema.fail(block, pred_src, "expected vector or array, found '{}'", .{pred_ty.fmt(sema.mod)}),
15376 };15378 };
15377 const vec_len = try sema.usizeCast(block, pred_src, vec_len_u64);15379 const vec_len = try sema.usizeCast(block, pred_src, vec_len_u64);
1537815380
...@@ -15399,12 +15401,12 @@ fn zirSelect(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -15399,12 +15401,12 @@ fn zirSelect(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
15399 var buf: Value.ElemValueBuffer = undefined;15401 var buf: Value.ElemValueBuffer = undefined;
15400 const elems = try sema.gpa.alloc(Value, vec_len);15402 const elems = try sema.gpa.alloc(Value, vec_len);
15401 for (elems) |*elem, i| {15403 for (elems) |*elem, i| {
15402 const pred_elem_val = pred_val.elemValueBuffer(i, &buf);15404 const pred_elem_val = pred_val.elemValueBuffer(sema.mod, i, &buf);
15403 const should_choose_a = pred_elem_val.toBool();15405 const should_choose_a = pred_elem_val.toBool();
15404 if (should_choose_a) {15406 if (should_choose_a) {
15405 elem.* = a_val.elemValueBuffer(i, &buf);15407 elem.* = a_val.elemValueBuffer(sema.mod, i, &buf);
15406 } else {15408 } else {
15407 elem.* = b_val.elemValueBuffer(i, &buf);15409 elem.* = b_val.elemValueBuffer(sema.mod, i, &buf);
15408 }15410 }
15409 }15411 }
1541015412
...@@ -15630,7 +15632,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -15630,7 +15632,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1563015632
15631 switch (ty.zigTypeTag()) {15633 switch (ty.zigTypeTag()) {
15632 .ComptimeFloat, .Float, .Vector => {},15634 .ComptimeFloat, .Float, .Vector => {},
15633 else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty.fmt(target)}),15635 else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty.fmt(sema.mod)}),
15634 }15636 }
1563515637
15636 const runtime_src = if (maybe_mulend1) |mulend1_val| rs: {15638 const runtime_src = if (maybe_mulend1) |mulend1_val| rs: {
...@@ -15704,10 +15706,9 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -15704,10 +15706,9 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
15704 break :modifier modifier_val.toEnum(std.builtin.CallOptions.Modifier);15706 break :modifier modifier_val.toEnum(std.builtin.CallOptions.Modifier);
15705 };15707 };
1570615708
15707 const target = sema.mod.getTarget();
15708 const args_ty = sema.typeOf(args);15709 const args_ty = sema.typeOf(args);
15709 if (!args_ty.isTuple() and args_ty.tag() != .empty_struct_literal) {15710 if (!args_ty.isTuple() and args_ty.tag() != .empty_struct_literal) {
15710 return sema.fail(block, args_src, "expected a tuple, found {}", .{args_ty.fmt(target)});15711 return sema.fail(block, args_src, "expected a tuple, found {}", .{args_ty.fmt(sema.mod)});
15711 }15712 }
1571215713
15713 var resolved_args: []Air.Inst.Ref = undefined;15714 var resolved_args: []Air.Inst.Ref = undefined;
...@@ -15744,10 +15745,9 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -15744,10 +15745,9 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
15744 const field_name = try sema.resolveConstString(block, name_src, extra.field_name);15745 const field_name = try sema.resolveConstString(block, name_src, extra.field_name);
15745 const field_ptr = sema.resolveInst(extra.field_ptr);15746 const field_ptr = sema.resolveInst(extra.field_ptr);
15746 const field_ptr_ty = sema.typeOf(field_ptr);15747 const field_ptr_ty = sema.typeOf(field_ptr);
15747 const target = sema.mod.getTarget();
1574815748
15749 if (struct_ty.zigTypeTag() != .Struct) {15749 if (struct_ty.zigTypeTag() != .Struct) {
15750 return sema.fail(block, ty_src, "expected struct type, found '{}'", .{struct_ty.fmt(target)});15750 return sema.fail(block, ty_src, "expected struct type, found '{}'", .{struct_ty.fmt(sema.mod)});
15751 }15751 }
15752 try sema.resolveTypeLayout(block, ty_src, struct_ty);15752 try sema.resolveTypeLayout(block, ty_src, struct_ty);
1575315753
...@@ -15756,7 +15756,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -15756,7 +15756,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
15756 return sema.failWithBadStructFieldAccess(block, struct_obj, name_src, field_name);15756 return sema.failWithBadStructFieldAccess(block, struct_obj, name_src, field_name);
1575715757
15758 if (field_ptr_ty.zigTypeTag() != .Pointer) {15758 if (field_ptr_ty.zigTypeTag() != .Pointer) {
15759 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{field_ptr_ty.fmt(target)});15759 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{field_ptr_ty.fmt(sema.mod)});
15760 }15760 }
15761 const field = struct_obj.fields.values()[field_index];15761 const field = struct_obj.fields.values()[field_index];
15762 const field_ptr_ty_info = field_ptr_ty.ptrInfo().data;15762 const field_ptr_ty_info = field_ptr_ty.ptrInfo().data;
...@@ -15773,11 +15773,11 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -15773,11 +15773,11 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
15773 ptr_ty_data.@"align" = field.abi_align;15773 ptr_ty_data.@"align" = field.abi_align;
15774 }15774 }
1577515775
15776 const actual_field_ptr_ty = try Type.ptr(sema.arena, target, ptr_ty_data);15776 const actual_field_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);
15777 const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, ptr_src);15777 const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, ptr_src);
1577815778
15779 ptr_ty_data.pointee_type = struct_ty;15779 ptr_ty_data.pointee_type = struct_ty;
15780 const result_ptr = try Type.ptr(sema.arena, target, ptr_ty_data);15780 const result_ptr = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);
1578115781
15782 if (try sema.resolveDefinedValue(block, src, casted_field_ptr)) |field_ptr_val| {15782 if (try sema.resolveDefinedValue(block, src, casted_field_ptr)) |field_ptr_val| {
15783 const payload = field_ptr_val.castTag(.field_ptr).?.data;15783 const payload = field_ptr_val.castTag(.field_ptr).?.data;
...@@ -15850,8 +15850,8 @@ fn analyzeMinMax(...@@ -15850,8 +15850,8 @@ fn analyzeMinMax(
15850 var rhs_buf: Value.ElemValueBuffer = undefined;15850 var rhs_buf: Value.ElemValueBuffer = undefined;
15851 const elems = try sema.arena.alloc(Value, vec_len);15851 const elems = try sema.arena.alloc(Value, vec_len);
15852 for (elems) |*elem, i| {15852 for (elems) |*elem, i| {
15853 const lhs_elem_val = lhs_val.elemValueBuffer(i, &lhs_buf);15853 const lhs_elem_val = lhs_val.elemValueBuffer(sema.mod, i, &lhs_buf);
15854 const rhs_elem_val = rhs_val.elemValueBuffer(i, &rhs_buf);15854 const rhs_elem_val = rhs_val.elemValueBuffer(sema.mod, i, &rhs_buf);
15855 elem.* = opFunc(lhs_elem_val, rhs_elem_val, target);15855 elem.* = opFunc(lhs_elem_val, rhs_elem_val, target);
15856 }15856 }
15857 return sema.addConstant(15857 return sema.addConstant(
...@@ -15878,18 +15878,17 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -15878,18 +15878,17 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
15878 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };15878 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
15879 const dest_ptr = sema.resolveInst(extra.dest);15879 const dest_ptr = sema.resolveInst(extra.dest);
15880 const dest_ptr_ty = sema.typeOf(dest_ptr);15880 const dest_ptr_ty = sema.typeOf(dest_ptr);
15881 const target = sema.mod.getTarget();
1588215881
15883 try sema.checkPtrOperand(block, dest_src, dest_ptr_ty);15882 try sema.checkPtrOperand(block, dest_src, dest_ptr_ty);
15884 if (dest_ptr_ty.isConstPtr()) {15883 if (dest_ptr_ty.isConstPtr()) {
15885 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty.fmt(target)});15884 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty.fmt(sema.mod)});
15886 }15885 }
1588715886
15888 const uncasted_src_ptr = sema.resolveInst(extra.source);15887 const uncasted_src_ptr = sema.resolveInst(extra.source);
15889 const uncasted_src_ptr_ty = sema.typeOf(uncasted_src_ptr);15888 const uncasted_src_ptr_ty = sema.typeOf(uncasted_src_ptr);
15890 try sema.checkPtrOperand(block, src_src, uncasted_src_ptr_ty);15889 try sema.checkPtrOperand(block, src_src, uncasted_src_ptr_ty);
15891 const src_ptr_info = uncasted_src_ptr_ty.ptrInfo().data;15890 const src_ptr_info = uncasted_src_ptr_ty.ptrInfo().data;
15892 const wanted_src_ptr_ty = try Type.ptr(sema.arena, target, .{15891 const wanted_src_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
15893 .pointee_type = dest_ptr_ty.elemType2(),15892 .pointee_type = dest_ptr_ty.elemType2(),
15894 .@"align" = src_ptr_info.@"align",15893 .@"align" = src_ptr_info.@"align",
15895 .@"addrspace" = src_ptr_info.@"addrspace",15894 .@"addrspace" = src_ptr_info.@"addrspace",
...@@ -15936,10 +15935,9 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -15936,10 +15935,9 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
15936 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };15935 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
15937 const dest_ptr = sema.resolveInst(extra.dest);15936 const dest_ptr = sema.resolveInst(extra.dest);
15938 const dest_ptr_ty = sema.typeOf(dest_ptr);15937 const dest_ptr_ty = sema.typeOf(dest_ptr);
15939 const target = sema.mod.getTarget();
15940 try sema.checkPtrOperand(block, dest_src, dest_ptr_ty);15938 try sema.checkPtrOperand(block, dest_src, dest_ptr_ty);
15941 if (dest_ptr_ty.isConstPtr()) {15939 if (dest_ptr_ty.isConstPtr()) {
15942 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty.fmt(target)});15940 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty.fmt(sema.mod)});
15943 }15941 }
15944 const elem_ty = dest_ptr_ty.elemType2();15942 const elem_ty = dest_ptr_ty.elemType2();
15945 const value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.byte), value_src);15943 const value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.byte), value_src);
...@@ -16057,7 +16055,7 @@ fn zirVarExtended(...@@ -16057,7 +16055,7 @@ fn zirVarExtended(
16057 });16055 });
1605816056
16059 new_var.* = .{16057 new_var.* = .{
16060 .owner_decl = sema.owner_decl,16058 .owner_decl = sema.owner_decl_index,
16061 .init = init_val,16059 .init = init_val,
16062 .is_extern = small.is_extern,16060 .is_extern = small.is_extern,
16063 .is_mutable = true, // TODO get rid of this unused field16061 .is_mutable = true, // TODO get rid of this unused field
...@@ -16294,7 +16292,7 @@ fn zirBuiltinExtern(...@@ -16294,7 +16292,7 @@ fn zirBuiltinExtern(
1629416292
16295 var ty = try sema.resolveType(block, ty_src, extra.lhs);16293 var ty = try sema.resolveType(block, ty_src, extra.lhs);
16296 const options_inst = sema.resolveInst(extra.rhs);16294 const options_inst = sema.resolveInst(extra.rhs);
16297 const target = sema.mod.getTarget();16295 const mod = sema.mod;
1629816296
16299 const options = options: {16297 const options = options: {
16300 const extern_options_ty = try sema.getBuiltinType(block, options_src, "ExternOptions");16298 const extern_options_ty = try sema.getBuiltinType(block, options_src, "ExternOptions");
...@@ -16315,11 +16313,11 @@ fn zirBuiltinExtern(...@@ -16315,11 +16313,11 @@ fn zirBuiltinExtern(
16315 var library_name: ?[]const u8 = null;16313 var library_name: ?[]const u8 = null;
16316 if (!library_name_val.isNull()) {16314 if (!library_name_val.isNull()) {
16317 const payload = library_name_val.castTag(.opt_payload).?.data;16315 const payload = library_name_val.castTag(.opt_payload).?.data;
16318 library_name = try payload.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, target);16316 library_name = try payload.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, mod);
16319 }16317 }
1632016318
16321 break :options std.builtin.ExternOptions{16319 break :options std.builtin.ExternOptions{
16322 .name = try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, target),16320 .name = try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, mod),
16323 .library_name = library_name,16321 .library_name = library_name,
16324 .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage),16322 .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage),
16325 .is_thread_local = is_thread_local_val.toBool(),16323 .is_thread_local = is_thread_local_val.toBool(),
...@@ -16344,8 +16342,10 @@ fn zirBuiltinExtern(...@@ -16344,8 +16342,10 @@ fn zirBuiltinExtern(
1634416342
16345 // TODO check duplicate extern16343 // TODO check duplicate extern
1634616344
16347 const new_decl = try sema.mod.allocateNewDecl(try sema.gpa.dupeZ(u8, options.name), sema.owner_decl.src_namespace, sema.owner_decl.src_node, null);16345 const new_decl_index = try mod.allocateNewDecl(sema.owner_decl.src_namespace, sema.owner_decl.src_node, null);
16348 errdefer new_decl.destroy(sema.mod);16346 errdefer mod.destroyDecl(new_decl_index);
16347 const new_decl = mod.declPtr(new_decl_index);
16348 new_decl.name = try sema.gpa.dupeZ(u8, options.name);
1634916349
16350 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);16350 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);
16351 errdefer new_decl_arena.deinit();16351 errdefer new_decl_arena.deinit();
...@@ -16355,7 +16355,7 @@ fn zirBuiltinExtern(...@@ -16355,7 +16355,7 @@ fn zirBuiltinExtern(
16355 errdefer new_decl_arena_allocator.destroy(new_var);16355 errdefer new_decl_arena_allocator.destroy(new_var);
1635616356
16357 new_var.* = .{16357 new_var.* = .{
16358 .owner_decl = sema.owner_decl,16358 .owner_decl = sema.owner_decl_index,
16359 .init = Value.initTag(.unreachable_value),16359 .init = Value.initTag(.unreachable_value),
16360 .is_extern = true,16360 .is_extern = true,
16361 .is_mutable = false, // TODO get rid of this unused field16361 .is_mutable = false, // TODO get rid of this unused field
...@@ -16378,13 +16378,13 @@ fn zirBuiltinExtern(...@@ -16378,13 +16378,13 @@ fn zirBuiltinExtern(
16378 new_decl.@"linksection" = null;16378 new_decl.@"linksection" = null;
16379 new_decl.has_tv = true;16379 new_decl.has_tv = true;
16380 new_decl.analysis = .complete;16380 new_decl.analysis = .complete;
16381 new_decl.generation = sema.mod.generation;16381 new_decl.generation = mod.generation;
1638216382
16383 const arena_state = try new_decl_arena_allocator.create(std.heap.ArenaAllocator.State);16383 const arena_state = try new_decl_arena_allocator.create(std.heap.ArenaAllocator.State);
16384 arena_state.* = new_decl_arena.state;16384 arena_state.* = new_decl_arena.state;
16385 new_decl.value_arena = arena_state;16385 new_decl.value_arena = arena_state;
1638616386
16387 const ref = try sema.analyzeDeclRef(new_decl);16387 const ref = try sema.analyzeDeclRef(new_decl_index);
16388 try sema.requireRuntimeBlock(block, src);16388 try sema.requireRuntimeBlock(block, src);
16389 return block.addBitCast(ty, ref);16389 return block.addBitCast(ty, ref);
16390}16390}
...@@ -16412,12 +16412,14 @@ fn validateVarType(...@@ -16412,12 +16412,14 @@ fn validateVarType(
16412) CompileError!void {16412) CompileError!void {
16413 if (try sema.validateRunTimeType(block, src, var_ty, is_extern)) return;16413 if (try sema.validateRunTimeType(block, src, var_ty, is_extern)) return;
1641416414
16415 const target = sema.mod.getTarget();16415 const mod = sema.mod;
16416
16416 const msg = msg: {16417 const msg = msg: {
16417 const msg = try sema.errMsg(block, src, "variable of type '{}' must be const or comptime", .{var_ty.fmt(target)});16418 const msg = try sema.errMsg(block, src, "variable of type '{}' must be const or comptime", .{var_ty.fmt(mod)});
16418 errdefer msg.destroy(sema.gpa);16419 errdefer msg.destroy(sema.gpa);
1641916420
16420 try sema.explainWhyTypeIsComptime(block, src, msg, src.toSrcLoc(block.src_decl), var_ty);16421 const src_decl = mod.declPtr(block.src_decl);
16422 try sema.explainWhyTypeIsComptime(block, src, msg, src.toSrcLoc(src_decl), var_ty);
1642116423
16422 break :msg msg;16424 break :msg msg;
16423 };16425 };
...@@ -16489,7 +16491,6 @@ fn explainWhyTypeIsComptime(...@@ -16489,7 +16491,6 @@ fn explainWhyTypeIsComptime(
16489 ty: Type,16491 ty: Type,
16490) CompileError!void {16492) CompileError!void {
16491 const mod = sema.mod;16493 const mod = sema.mod;
16492 const target = mod.getTarget();
16493 switch (ty.zigTypeTag()) {16494 switch (ty.zigTypeTag()) {
16494 .Bool,16495 .Bool,
16495 .Int,16496 .Int,
...@@ -16503,7 +16504,7 @@ fn explainWhyTypeIsComptime(...@@ -16503,7 +16504,7 @@ fn explainWhyTypeIsComptime(
1650316504
16504 .Fn => {16505 .Fn => {
16505 try mod.errNoteNonLazy(src_loc, msg, "use '*const {}' for a function pointer type", .{16506 try mod.errNoteNonLazy(src_loc, msg, "use '*const {}' for a function pointer type", .{
16506 ty.fmt(target),16507 ty.fmt(sema.mod),
16507 });16508 });
16508 },16509 },
1650916510
...@@ -16534,7 +16535,7 @@ fn explainWhyTypeIsComptime(...@@ -16534,7 +16535,7 @@ fn explainWhyTypeIsComptime(
16534 if (ty.castTag(.@"struct")) |payload| {16535 if (ty.castTag(.@"struct")) |payload| {
16535 const struct_obj = payload.data;16536 const struct_obj = payload.data;
16536 for (struct_obj.fields.values()) |field, i| {16537 for (struct_obj.fields.values()) |field, i| {
16537 const field_src_loc = struct_obj.fieldSrcLoc(sema.gpa, .{16538 const field_src_loc = struct_obj.fieldSrcLoc(sema.mod, .{
16538 .index = i,16539 .index = i,
16539 .range = .type,16540 .range = .type,
16540 });16541 });
...@@ -16551,7 +16552,7 @@ fn explainWhyTypeIsComptime(...@@ -16551,7 +16552,7 @@ fn explainWhyTypeIsComptime(
16551 if (ty.cast(Type.Payload.Union)) |payload| {16552 if (ty.cast(Type.Payload.Union)) |payload| {
16552 const union_obj = payload.data;16553 const union_obj = payload.data;
16553 for (union_obj.fields.values()) |field, i| {16554 for (union_obj.fields.values()) |field, i| {
16554 const field_src_loc = union_obj.fieldSrcLoc(sema.gpa, .{16555 const field_src_loc = union_obj.fieldSrcLoc(sema.mod, .{
16555 .index = i,16556 .index = i,
16556 .range = .type,16557 .range = .type,
16557 });16558 });
...@@ -16668,7 +16669,7 @@ fn panicWithMsg(...@@ -16668,7 +16669,7 @@ fn panicWithMsg(
16668 const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace");16669 const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace");
16669 const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty);16670 const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty);
16670 const target = mod.getTarget();16671 const target = mod.getTarget();
16671 const ptr_stack_trace_ty = try Type.ptr(arena, target, .{16672 const ptr_stack_trace_ty = try Type.ptr(arena, mod, .{
16672 .pointee_type = stack_trace_ty,16673 .pointee_type = stack_trace_ty,
16673 .@"addrspace" = target_util.defaultAddressSpace(target, .global_constant), // TODO might need a place that is more dynamic16674 .@"addrspace" = target_util.defaultAddressSpace(target, .global_constant), // TODO might need a place that is more dynamic
16674 });16675 });
...@@ -16748,8 +16749,6 @@ fn fieldVal(...@@ -16748,8 +16749,6 @@ fn fieldVal(
16748 else16749 else
16749 object_ty;16750 object_ty;
1675016751
16751 const target = sema.mod.getTarget();
16752
16753 switch (inner_ty.zigTypeTag()) {16752 switch (inner_ty.zigTypeTag()) {
16754 .Array => {16753 .Array => {
16755 if (mem.eql(u8, field_name, "len")) {16754 if (mem.eql(u8, field_name, "len")) {
...@@ -16762,7 +16761,7 @@ fn fieldVal(...@@ -16762,7 +16761,7 @@ fn fieldVal(
16762 block,16761 block,
16763 field_name_src,16762 field_name_src,
16764 "no member named '{s}' in '{}'",16763 "no member named '{s}' in '{}'",
16765 .{ field_name, object_ty.fmt(target) },16764 .{ field_name, object_ty.fmt(sema.mod) },
16766 );16765 );
16767 }16766 }
16768 },16767 },
...@@ -16786,7 +16785,7 @@ fn fieldVal(...@@ -16786,7 +16785,7 @@ fn fieldVal(
16786 block,16785 block,
16787 field_name_src,16786 field_name_src,
16788 "no member named '{s}' in '{}'",16787 "no member named '{s}' in '{}'",
16789 .{ field_name, object_ty.fmt(target) },16788 .{ field_name, object_ty.fmt(sema.mod) },
16790 );16789 );
16791 }16790 }
16792 } else if (ptr_info.pointee_type.zigTypeTag() == .Array) {16791 } else if (ptr_info.pointee_type.zigTypeTag() == .Array) {
...@@ -16800,7 +16799,7 @@ fn fieldVal(...@@ -16800,7 +16799,7 @@ fn fieldVal(
16800 block,16799 block,
16801 field_name_src,16800 field_name_src,
16802 "no member named '{s}' in '{}'",16801 "no member named '{s}' in '{}'",
16803 .{ field_name, ptr_info.pointee_type.fmt(target) },16802 .{ field_name, ptr_info.pointee_type.fmt(sema.mod) },
16804 );16803 );
16805 }16804 }
16806 }16805 }
...@@ -16822,7 +16821,7 @@ fn fieldVal(...@@ -16822,7 +16821,7 @@ fn fieldVal(
16822 break :blk entry.key_ptr.*;16821 break :blk entry.key_ptr.*;
16823 }16822 }
16824 return sema.fail(block, src, "no error named '{s}' in '{}'", .{16823 return sema.fail(block, src, "no error named '{s}' in '{}'", .{
16825 field_name, child_type.fmt(target),16824 field_name, child_type.fmt(sema.mod),
16826 });16825 });
16827 } else (try sema.mod.getErrorValue(field_name)).key;16826 } else (try sema.mod.getErrorValue(field_name)).key;
1682816827
...@@ -16876,10 +16875,10 @@ fn fieldVal(...@@ -16876,10 +16875,10 @@ fn fieldVal(
16876 else => unreachable,16875 else => unreachable,
16877 };16876 };
16878 return sema.fail(block, src, "{s} '{}' has no member named '{s}'", .{16877 return sema.fail(block, src, "{s} '{}' has no member named '{s}'", .{
16879 kw_name, child_type.fmt(target), field_name,16878 kw_name, child_type.fmt(sema.mod), field_name,
16880 });16879 });
16881 },16880 },
16882 else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(target)}),16881 else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(sema.mod)}),
16883 }16882 }
16884 },16883 },
16885 .Struct => if (is_pointer_to) {16884 .Struct => if (is_pointer_to) {
...@@ -16898,7 +16897,7 @@ fn fieldVal(...@@ -16898,7 +16897,7 @@ fn fieldVal(
16898 },16897 },
16899 else => {},16898 else => {},
16900 }16899 }
16901 return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(target)});16900 return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(sema.mod)});
16902}16901}
1690316902
16904fn fieldPtr(16903fn fieldPtr(
...@@ -16912,12 +16911,11 @@ fn fieldPtr(...@@ -16912,12 +16911,11 @@ fn fieldPtr(
16912 // When editing this function, note that there is corresponding logic to be edited16911 // When editing this function, note that there is corresponding logic to be edited
16913 // in `fieldVal`. This function takes a pointer and returns a pointer.16912 // in `fieldVal`. This function takes a pointer and returns a pointer.
1691416913
16915 const target = sema.mod.getTarget();
16916 const object_ptr_src = src; // TODO better source location16914 const object_ptr_src = src; // TODO better source location
16917 const object_ptr_ty = sema.typeOf(object_ptr);16915 const object_ptr_ty = sema.typeOf(object_ptr);
16918 const object_ty = switch (object_ptr_ty.zigTypeTag()) {16916 const object_ty = switch (object_ptr_ty.zigTypeTag()) {
16919 .Pointer => object_ptr_ty.elemType(),16917 .Pointer => object_ptr_ty.elemType(),
16920 else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty.fmt(target)}),16918 else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty.fmt(sema.mod)}),
16921 };16919 };
1692216920
16923 // Zig allows dereferencing a single pointer during field lookup. Note that16921 // Zig allows dereferencing a single pointer during field lookup. Note that
...@@ -16945,7 +16943,7 @@ fn fieldPtr(...@@ -16945,7 +16943,7 @@ fn fieldPtr(
16945 block,16943 block,
16946 field_name_src,16944 field_name_src,
16947 "no member named '{s}' in '{}'",16945 "no member named '{s}' in '{}'",
16948 .{ field_name, object_ty.fmt(target) },16946 .{ field_name, object_ty.fmt(sema.mod) },
16949 );16947 );
16950 }16948 }
16951 },16949 },
...@@ -16971,7 +16969,7 @@ fn fieldPtr(...@@ -16971,7 +16969,7 @@ fn fieldPtr(
16971 }16969 }
16972 try sema.requireRuntimeBlock(block, src);16970 try sema.requireRuntimeBlock(block, src);
1697316971
16974 const result_ty = try Type.ptr(sema.arena, target, .{16972 const result_ty = try Type.ptr(sema.arena, sema.mod, .{
16975 .pointee_type = slice_ptr_ty,16973 .pointee_type = slice_ptr_ty,
16976 .mutable = object_ptr_ty.ptrIsMutable(),16974 .mutable = object_ptr_ty.ptrIsMutable(),
16977 .@"addrspace" = object_ptr_ty.ptrAddressSpace(),16975 .@"addrspace" = object_ptr_ty.ptrAddressSpace(),
...@@ -16985,13 +16983,13 @@ fn fieldPtr(...@@ -16985,13 +16983,13 @@ fn fieldPtr(
1698516983
16986 return sema.analyzeDeclRef(try anon_decl.finish(16984 return sema.analyzeDeclRef(try anon_decl.finish(
16987 Type.usize,16985 Type.usize,
16988 try Value.Tag.int_u64.create(anon_decl.arena(), val.sliceLen(target)),16986 try Value.Tag.int_u64.create(anon_decl.arena(), val.sliceLen(sema.mod)),
16989 0, // default alignment16987 0, // default alignment
16990 ));16988 ));
16991 }16989 }
16992 try sema.requireRuntimeBlock(block, src);16990 try sema.requireRuntimeBlock(block, src);
1699316991
16994 const result_ty = try Type.ptr(sema.arena, target, .{16992 const result_ty = try Type.ptr(sema.arena, sema.mod, .{
16995 .pointee_type = Type.usize,16993 .pointee_type = Type.usize,
16996 .mutable = object_ptr_ty.ptrIsMutable(),16994 .mutable = object_ptr_ty.ptrIsMutable(),
16997 .@"addrspace" = object_ptr_ty.ptrAddressSpace(),16995 .@"addrspace" = object_ptr_ty.ptrAddressSpace(),
...@@ -17003,7 +17001,7 @@ fn fieldPtr(...@@ -17003,7 +17001,7 @@ fn fieldPtr(
17003 block,17001 block,
17004 field_name_src,17002 field_name_src,
17005 "no member named '{s}' in '{}'",17003 "no member named '{s}' in '{}'",
17006 .{ field_name, object_ty.fmt(target) },17004 .{ field_name, object_ty.fmt(sema.mod) },
17007 );17005 );
17008 }17006 }
17009 },17007 },
...@@ -17027,7 +17025,7 @@ fn fieldPtr(...@@ -17027,7 +17025,7 @@ fn fieldPtr(
17027 break :blk entry.key_ptr.*;17025 break :blk entry.key_ptr.*;
17028 }17026 }
17029 return sema.fail(block, src, "no error named '{s}' in '{}'", .{17027 return sema.fail(block, src, "no error named '{s}' in '{}'", .{
17030 field_name, child_type.fmt(target),17028 field_name, child_type.fmt(sema.mod),
17031 });17029 });
17032 } else (try sema.mod.getErrorValue(field_name)).key;17030 } else (try sema.mod.getErrorValue(field_name)).key;
1703317031
...@@ -17085,7 +17083,7 @@ fn fieldPtr(...@@ -17085,7 +17083,7 @@ fn fieldPtr(
17085 }17083 }
17086 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);17084 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
17087 },17085 },
17088 else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(target)}),17086 else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(sema.mod)}),
17089 }17087 }
17090 },17088 },
17091 .Struct => {17089 .Struct => {
...@@ -17104,7 +17102,7 @@ fn fieldPtr(...@@ -17104,7 +17102,7 @@ fn fieldPtr(
17104 },17102 },
17105 else => {},17103 else => {},
17106 }17104 }
17107 return sema.fail(block, src, "type '{}' does not support field access (fieldPtr, {}.{s})", .{ object_ty.fmt(target), object_ptr_ty.fmt(target), field_name });17105 return sema.fail(block, src, "type '{}' does not support field access (fieldPtr, {}.{s})", .{ object_ty.fmt(sema.mod), object_ptr_ty.fmt(sema.mod), field_name });
17108}17106}
1710917107
17110fn fieldCallBind(17108fn fieldCallBind(
...@@ -17118,13 +17116,12 @@ fn fieldCallBind(...@@ -17118,13 +17116,12 @@ fn fieldCallBind(
17118 // When editing this function, note that there is corresponding logic to be edited17116 // When editing this function, note that there is corresponding logic to be edited
17119 // in `fieldVal`. This function takes a pointer and returns a pointer.17117 // in `fieldVal`. This function takes a pointer and returns a pointer.
1712017118
17121 const target = sema.mod.getTarget();
17122 const raw_ptr_src = src; // TODO better source location17119 const raw_ptr_src = src; // TODO better source location
17123 const raw_ptr_ty = sema.typeOf(raw_ptr);17120 const raw_ptr_ty = sema.typeOf(raw_ptr);
17124 const inner_ty = if (raw_ptr_ty.zigTypeTag() == .Pointer and raw_ptr_ty.ptrSize() == .One)17121 const inner_ty = if (raw_ptr_ty.zigTypeTag() == .Pointer and raw_ptr_ty.ptrSize() == .One)
17125 raw_ptr_ty.childType()17122 raw_ptr_ty.childType()
17126 else17123 else
17127 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(target)});17124 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(sema.mod)});
1712817125
17129 // Optionally dereference a second pointer to get the concrete type.17126 // Optionally dereference a second pointer to get the concrete type.
17130 const is_double_ptr = inner_ty.zigTypeTag() == .Pointer and inner_ty.ptrSize() == .One;17127 const is_double_ptr = inner_ty.zigTypeTag() == .Pointer and inner_ty.ptrSize() == .One;
...@@ -17184,7 +17181,7 @@ fn fieldCallBind(...@@ -17184,7 +17181,7 @@ fn fieldCallBind(
17184 first_param_type.zigTypeTag() == .Pointer and17181 first_param_type.zigTypeTag() == .Pointer and
17185 (first_param_type.ptrSize() == .One or17182 (first_param_type.ptrSize() == .One or
17186 first_param_type.ptrSize() == .C) and17183 first_param_type.ptrSize() == .C) and
17187 first_param_type.childType().eql(concrete_ty, target)))17184 first_param_type.childType().eql(concrete_ty, sema.mod)))
17188 {17185 {
17189 // zig fmt: on17186 // zig fmt: on
17190 // TODO: bound fn calls on rvalues should probably17187 // TODO: bound fn calls on rvalues should probably
...@@ -17195,7 +17192,7 @@ fn fieldCallBind(...@@ -17195,7 +17192,7 @@ fn fieldCallBind(
17195 .arg0_inst = object_ptr,17192 .arg0_inst = object_ptr,
17196 });17193 });
17197 return sema.addConstant(ty, value);17194 return sema.addConstant(ty, value);
17198 } else if (first_param_type.eql(concrete_ty, target)) {17195 } else if (first_param_type.eql(concrete_ty, sema.mod)) {
17199 var deref = try sema.analyzeLoad(block, src, object_ptr, src);17196 var deref = try sema.analyzeLoad(block, src, object_ptr, src);
17200 const ty = Type.Tag.bound_fn.init();17197 const ty = Type.Tag.bound_fn.init();
17201 const value = try Value.Tag.bound_fn.create(arena, .{17198 const value = try Value.Tag.bound_fn.create(arena, .{
...@@ -17211,7 +17208,7 @@ fn fieldCallBind(...@@ -17211,7 +17208,7 @@ fn fieldCallBind(
17211 else => {},17208 else => {},
17212 }17209 }
1721317210
17214 return sema.fail(block, src, "type '{}' has no field or member function named '{s}'", .{ concrete_ty.fmt(target), field_name });17211 return sema.fail(block, src, "type '{}' has no field or member function named '{s}'", .{ concrete_ty.fmt(sema.mod), field_name });
17215}17212}
1721617213
17217fn finishFieldCallBind(17214fn finishFieldCallBind(
...@@ -17224,8 +17221,7 @@ fn finishFieldCallBind(...@@ -17224,8 +17221,7 @@ fn finishFieldCallBind(
17224 object_ptr: Air.Inst.Ref,17221 object_ptr: Air.Inst.Ref,
17225) CompileError!Air.Inst.Ref {17222) CompileError!Air.Inst.Ref {
17226 const arena = sema.arena;17223 const arena = sema.arena;
17227 const target = sema.mod.getTarget();17224 const ptr_field_ty = try Type.ptr(arena, sema.mod, .{
17228 const ptr_field_ty = try Type.ptr(arena, target, .{
17229 .pointee_type = field_ty,17225 .pointee_type = field_ty,
17230 .mutable = ptr_ty.ptrIsMutable(),17226 .mutable = ptr_ty.ptrIsMutable(),
17231 .@"addrspace" = ptr_ty.ptrAddressSpace(),17227 .@"addrspace" = ptr_ty.ptrAddressSpace(),
...@@ -17254,9 +17250,10 @@ fn namespaceLookup(...@@ -17254,9 +17250,10 @@ fn namespaceLookup(
17254 src: LazySrcLoc,17250 src: LazySrcLoc,
17255 namespace: *Namespace,17251 namespace: *Namespace,
17256 decl_name: []const u8,17252 decl_name: []const u8,
17257) CompileError!?*Decl {17253) CompileError!?Decl.Index {
17258 const gpa = sema.gpa;17254 const gpa = sema.gpa;
17259 if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |decl| {17255 if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |decl_index| {
17256 const decl = sema.mod.declPtr(decl_index);
17260 if (!decl.is_pub and decl.getFileScope() != block.getFileScope()) {17257 if (!decl.is_pub and decl.getFileScope() != block.getFileScope()) {
17261 const msg = msg: {17258 const msg = msg: {
17262 const msg = try sema.errMsg(block, src, "'{s}' is not marked 'pub'", .{17259 const msg = try sema.errMsg(block, src, "'{s}' is not marked 'pub'", .{
...@@ -17268,7 +17265,7 @@ fn namespaceLookup(...@@ -17268,7 +17265,7 @@ fn namespaceLookup(
17268 };17265 };
17269 return sema.failWithOwnedErrorMsg(block, msg);17266 return sema.failWithOwnedErrorMsg(block, msg);
17270 }17267 }
17271 return decl;17268 return decl_index;
17272 }17269 }
17273 return null;17270 return null;
17274}17271}
...@@ -17377,7 +17374,7 @@ fn structFieldPtrByIndex(...@@ -17377,7 +17374,7 @@ fn structFieldPtrByIndex(
17377 ptr_ty_data.@"align" = field.abi_align;17374 ptr_ty_data.@"align" = field.abi_align;
17378 }17375 }
1737917376
17380 const ptr_field_ty = try Type.ptr(sema.arena, target, ptr_ty_data);17377 const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);
1738117378
17382 if (field.is_comptime) {17379 if (field.is_comptime) {
17383 var anon_decl = try block.startAnonDecl(field_src);17380 var anon_decl = try block.startAnonDecl(field_src);
...@@ -17476,15 +17473,14 @@ fn tupleFieldIndex(...@@ -17476,15 +17473,14 @@ fn tupleFieldIndex(
17476 field_name: []const u8,17473 field_name: []const u8,
17477 field_name_src: LazySrcLoc,17474 field_name_src: LazySrcLoc,
17478) CompileError!u32 {17475) CompileError!u32 {
17479 const target = sema.mod.getTarget();
17480 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| {17476 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| {
17481 return sema.fail(block, field_name_src, "tuple {} has no such field '{s}': {s}", .{17477 return sema.fail(block, field_name_src, "tuple {} has no such field '{s}': {s}", .{
17482 tuple_ty.fmt(target), field_name, @errorName(err),17478 tuple_ty.fmt(sema.mod), field_name, @errorName(err),
17483 });17479 });
17484 };17480 };
17485 if (field_index >= tuple_ty.structFieldCount()) {17481 if (field_index >= tuple_ty.structFieldCount()) {
17486 return sema.fail(block, field_name_src, "tuple {} has no such field '{s}'", .{17482 return sema.fail(block, field_name_src, "tuple {} has no such field '{s}'", .{
17487 tuple_ty.fmt(target), field_name,17483 tuple_ty.fmt(sema.mod), field_name,
17488 });17484 });
17489 }17485 }
17490 return field_index;17486 return field_index;
...@@ -17535,8 +17531,7 @@ fn unionFieldPtr(...@@ -17535,8 +17531,7 @@ fn unionFieldPtr(
17535 const union_obj = union_ty.cast(Type.Payload.Union).?.data;17531 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
17536 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);17532 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
17537 const field = union_obj.fields.values()[field_index];17533 const field = union_obj.fields.values()[field_index];
17538 const target = sema.mod.getTarget();17534 const ptr_field_ty = try Type.ptr(arena, sema.mod, .{
17539 const ptr_field_ty = try Type.ptr(arena, target, .{
17540 .pointee_type = field.ty,17535 .pointee_type = field.ty,
17541 .mutable = union_ptr_ty.ptrIsMutable(),17536 .mutable = union_ptr_ty.ptrIsMutable(),
17542 .@"addrspace" = union_ptr_ty.ptrAddressSpace(),17537 .@"addrspace" = union_ptr_ty.ptrAddressSpace(),
...@@ -17559,7 +17554,7 @@ fn unionFieldPtr(...@@ -17559,7 +17554,7 @@ fn unionFieldPtr(
17559 // .data = field_index,17554 // .data = field_index,
17560 //};17555 //};
17561 //const field_tag = Value.initPayload(&field_tag_buf.base);17556 //const field_tag = Value.initPayload(&field_tag_buf.base);
17562 //const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, target);17557 //const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, mod);
17563 //if (!tag_matches) {17558 //if (!tag_matches) {
17564 // // TODO enhance this saying which one was active17559 // // TODO enhance this saying which one was active
17565 // // and which one was accessed, and showing where the union was declared.17560 // // and which one was accessed, and showing where the union was declared.
...@@ -17608,8 +17603,7 @@ fn unionFieldVal(...@@ -17608,8 +17603,7 @@ fn unionFieldVal(
17608 .data = field_index,17603 .data = field_index,
17609 };17604 };
17610 const field_tag = Value.initPayload(&field_tag_buf.base);17605 const field_tag = Value.initPayload(&field_tag_buf.base);
17611 const target = sema.mod.getTarget();17606 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, sema.mod);
17612 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, target);
17613 switch (union_obj.layout) {17607 switch (union_obj.layout) {
17614 .Auto => {17608 .Auto => {
17615 if (tag_matches) {17609 if (tag_matches) {
...@@ -17630,7 +17624,7 @@ fn unionFieldVal(...@@ -17630,7 +17624,7 @@ fn unionFieldVal(
17630 if (tag_matches) {17624 if (tag_matches) {
17631 return sema.addConstant(field.ty, tag_and_val.val);17625 return sema.addConstant(field.ty, tag_and_val.val);
17632 } else {17626 } else {
17633 const old_ty = union_ty.unionFieldType(tag_and_val.tag, target);17627 const old_ty = union_ty.unionFieldType(tag_and_val.tag, sema.mod);
17634 const new_val = try sema.bitCastVal(block, src, tag_and_val.val, old_ty, field.ty, 0);17628 const new_val = try sema.bitCastVal(block, src, tag_and_val.val, old_ty, field.ty, 0);
17635 return sema.addConstant(field.ty, new_val);17629 return sema.addConstant(field.ty, new_val);
17636 }17630 }
...@@ -17655,17 +17649,17 @@ fn elemPtr(...@@ -17655,17 +17649,17 @@ fn elemPtr(
17655 const target = sema.mod.getTarget();17649 const target = sema.mod.getTarget();
17656 const indexable_ty = switch (indexable_ptr_ty.zigTypeTag()) {17650 const indexable_ty = switch (indexable_ptr_ty.zigTypeTag()) {
17657 .Pointer => indexable_ptr_ty.elemType(),17651 .Pointer => indexable_ptr_ty.elemType(),
17658 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(target)}),17652 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(sema.mod)}),
17659 };17653 };
17660 if (!indexable_ty.isIndexable()) {17654 if (!indexable_ty.isIndexable()) {
17661 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty.fmt(target)});17655 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty.fmt(sema.mod)});
17662 }17656 }
1766317657
17664 switch (indexable_ty.zigTypeTag()) {17658 switch (indexable_ty.zigTypeTag()) {
17665 .Pointer => {17659 .Pointer => {
17666 // In all below cases, we have to deref the ptr operand to get the actual indexable pointer.17660 // In all below cases, we have to deref the ptr operand to get the actual indexable pointer.
17667 const indexable = try sema.analyzeLoad(block, indexable_ptr_src, indexable_ptr, indexable_ptr_src);17661 const indexable = try sema.analyzeLoad(block, indexable_ptr_src, indexable_ptr, indexable_ptr_src);
17668 const result_ty = try indexable_ty.elemPtrType(sema.arena, target);17662 const result_ty = try indexable_ty.elemPtrType(sema.arena, sema.mod);
17669 switch (indexable_ty.ptrSize()) {17663 switch (indexable_ty.ptrSize()) {
17670 .Slice => return sema.elemPtrSlice(block, indexable_ptr_src, indexable, elem_index_src, elem_index),17664 .Slice => return sema.elemPtrSlice(block, indexable_ptr_src, indexable, elem_index_src, elem_index),
17671 .Many, .C => {17665 .Many, .C => {
...@@ -17676,7 +17670,7 @@ fn elemPtr(...@@ -17676,7 +17670,7 @@ fn elemPtr(
17676 const ptr_val = maybe_ptr_val orelse break :rs indexable_ptr_src;17670 const ptr_val = maybe_ptr_val orelse break :rs indexable_ptr_src;
17677 const index_val = maybe_index_val orelse break :rs elem_index_src;17671 const index_val = maybe_index_val orelse break :rs elem_index_src;
17678 const index = @intCast(usize, index_val.toUnsignedInt(target));17672 const index = @intCast(usize, index_val.toUnsignedInt(target));
17679 const elem_ptr = try ptr_val.elemPtr(indexable_ty, sema.arena, index, target);17673 const elem_ptr = try ptr_val.elemPtr(indexable_ty, sema.arena, index, sema.mod);
17680 return sema.addConstant(result_ty, elem_ptr);17674 return sema.addConstant(result_ty, elem_ptr);
17681 };17675 };
1768217676
...@@ -17713,7 +17707,7 @@ fn elemVal(...@@ -17713,7 +17707,7 @@ fn elemVal(
17713 const target = sema.mod.getTarget();17707 const target = sema.mod.getTarget();
1771417708
17715 if (!indexable_ty.isIndexable()) {17709 if (!indexable_ty.isIndexable()) {
17716 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty.fmt(target)});17710 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty.fmt(sema.mod)});
17717 }17711 }
1771817712
17719 // TODO in case of a vector of pointers, we need to detect whether the element17713 // TODO in case of a vector of pointers, we need to detect whether the element
...@@ -17731,7 +17725,7 @@ fn elemVal(...@@ -17731,7 +17725,7 @@ fn elemVal(
17731 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;17725 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;
17732 const index_val = maybe_index_val orelse break :rs elem_index_src;17726 const index_val = maybe_index_val orelse break :rs elem_index_src;
17733 const index = @intCast(usize, index_val.toUnsignedInt(target));17727 const index = @intCast(usize, index_val.toUnsignedInt(target));
17734 const elem_ptr_val = try indexable_val.elemPtr(indexable_ty, sema.arena, index, target);17728 const elem_ptr_val = try indexable_val.elemPtr(indexable_ty, sema.arena, index, sema.mod);
17735 if (try sema.pointerDeref(block, indexable_src, elem_ptr_val, indexable_ty)) |elem_val| {17729 if (try sema.pointerDeref(block, indexable_src, elem_ptr_val, indexable_ty)) |elem_val| {
17736 return sema.addConstant(indexable_ty.elemType2(), elem_val);17730 return sema.addConstant(indexable_ty.elemType2(), elem_val);
17737 }17731 }
...@@ -17785,8 +17779,7 @@ fn tupleFieldPtr(...@@ -17785,8 +17779,7 @@ fn tupleFieldPtr(
17785 }17779 }
1778617780
17787 const field_ty = tuple_fields.types[field_index];17781 const field_ty = tuple_fields.types[field_index];
17788 const target = sema.mod.getTarget();17782 const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{
17789 const ptr_field_ty = try Type.ptr(sema.arena, target, .{
17790 .pointee_type = field_ty,17783 .pointee_type = field_ty,
17791 .mutable = tuple_ptr_ty.ptrIsMutable(),17784 .mutable = tuple_ptr_ty.ptrIsMutable(),
17792 .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(),17785 .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(),
...@@ -17881,7 +17874,7 @@ fn elemValArray(...@@ -17881,7 +17874,7 @@ fn elemValArray(
17881 }17874 }
17882 if (maybe_index_val) |index_val| {17875 if (maybe_index_val) |index_val| {
17883 const index = @intCast(usize, index_val.toUnsignedInt(target));17876 const index = @intCast(usize, index_val.toUnsignedInt(target));
17884 const elem_val = try array_val.elemValue(sema.arena, index);17877 const elem_val = try array_val.elemValue(sema.mod, sema.arena, index);
17885 return sema.addConstant(elem_ty, elem_val);17878 return sema.addConstant(elem_ty, elem_val);
17886 }17879 }
17887 }17880 }
...@@ -17914,7 +17907,7 @@ fn elemPtrArray(...@@ -17914,7 +17907,7 @@ fn elemPtrArray(
17914 const array_sent = array_ty.sentinel() != null;17907 const array_sent = array_ty.sentinel() != null;
17915 const array_len = array_ty.arrayLen();17908 const array_len = array_ty.arrayLen();
17916 const array_len_s = array_len + @boolToInt(array_sent);17909 const array_len_s = array_len + @boolToInt(array_sent);
17917 const elem_ptr_ty = try array_ptr_ty.elemPtrType(sema.arena, target);17910 const elem_ptr_ty = try array_ptr_ty.elemPtrType(sema.arena, sema.mod);
1791817911
17919 if (array_len_s == 0) {17912 if (array_len_s == 0) {
17920 return sema.fail(block, elem_index_src, "indexing into empty array", .{});17913 return sema.fail(block, elem_index_src, "indexing into empty array", .{});
...@@ -17937,7 +17930,7 @@ fn elemPtrArray(...@@ -17937,7 +17930,7 @@ fn elemPtrArray(
17937 }17930 }
17938 if (maybe_index_val) |index_val| {17931 if (maybe_index_val) |index_val| {
17939 const index = @intCast(usize, index_val.toUnsignedInt(target));17932 const index = @intCast(usize, index_val.toUnsignedInt(target));
17940 const elem_ptr = try array_ptr_val.elemPtr(array_ptr_ty, sema.arena, index, target);17933 const elem_ptr = try array_ptr_val.elemPtr(array_ptr_ty, sema.arena, index, sema.mod);
17941 return sema.addConstant(elem_ptr_ty, elem_ptr);17934 return sema.addConstant(elem_ptr_ty, elem_ptr);
17942 }17935 }
17943 }17936 }
...@@ -17977,7 +17970,7 @@ fn elemValSlice(...@@ -17977,7 +17970,7 @@ fn elemValSlice(
1797717970
17978 if (maybe_slice_val) |slice_val| {17971 if (maybe_slice_val) |slice_val| {
17979 runtime_src = elem_index_src;17972 runtime_src = elem_index_src;
17980 const slice_len = slice_val.sliceLen(target);17973 const slice_len = slice_val.sliceLen(sema.mod);
17981 const slice_len_s = slice_len + @boolToInt(slice_sent);17974 const slice_len_s = slice_len + @boolToInt(slice_sent);
17982 if (slice_len_s == 0) {17975 if (slice_len_s == 0) {
17983 return sema.fail(block, elem_index_src, "indexing into empty slice", .{});17976 return sema.fail(block, elem_index_src, "indexing into empty slice", .{});
...@@ -17988,7 +17981,7 @@ fn elemValSlice(...@@ -17988,7 +17981,7 @@ fn elemValSlice(
17988 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";17981 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
17989 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });17982 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
17990 }17983 }
17991 const elem_ptr_val = try slice_val.elemPtr(slice_ty, sema.arena, index, target);17984 const elem_ptr_val = try slice_val.elemPtr(slice_ty, sema.arena, index, sema.mod);
17992 if (try sema.pointerDeref(block, slice_src, elem_ptr_val, slice_ty)) |elem_val| {17985 if (try sema.pointerDeref(block, slice_src, elem_ptr_val, slice_ty)) |elem_val| {
17993 return sema.addConstant(elem_ty, elem_val);17986 return sema.addConstant(elem_ty, elem_val);
17994 }17987 }
...@@ -17999,7 +17992,7 @@ fn elemValSlice(...@@ -17999,7 +17992,7 @@ fn elemValSlice(
17999 try sema.requireRuntimeBlock(block, runtime_src);17992 try sema.requireRuntimeBlock(block, runtime_src);
18000 if (block.wantSafety()) {17993 if (block.wantSafety()) {
18001 const len_inst = if (maybe_slice_val) |slice_val|17994 const len_inst = if (maybe_slice_val) |slice_val|
18002 try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(target))17995 try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(sema.mod))
18003 else17996 else
18004 try block.addTyOp(.slice_len, Type.usize, slice);17997 try block.addTyOp(.slice_len, Type.usize, slice);
18005 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;17998 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
...@@ -18020,7 +18013,7 @@ fn elemPtrSlice(...@@ -18020,7 +18013,7 @@ fn elemPtrSlice(
18020 const target = sema.mod.getTarget();18013 const target = sema.mod.getTarget();
18021 const slice_ty = sema.typeOf(slice);18014 const slice_ty = sema.typeOf(slice);
18022 const slice_sent = slice_ty.sentinel() != null;18015 const slice_sent = slice_ty.sentinel() != null;
18023 const elem_ptr_ty = try slice_ty.elemPtrType(sema.arena, target);18016 const elem_ptr_ty = try slice_ty.elemPtrType(sema.arena, sema.mod);
1802418017
18025 const maybe_undef_slice_val = try sema.resolveMaybeUndefVal(block, slice_src, slice);18018 const maybe_undef_slice_val = try sema.resolveMaybeUndefVal(block, slice_src, slice);
18026 // index must be defined since it can index out of bounds18019 // index must be defined since it can index out of bounds
...@@ -18030,7 +18023,7 @@ fn elemPtrSlice(...@@ -18030,7 +18023,7 @@ fn elemPtrSlice(
18030 if (slice_val.isUndef()) {18023 if (slice_val.isUndef()) {
18031 return sema.addConstUndef(elem_ptr_ty);18024 return sema.addConstUndef(elem_ptr_ty);
18032 }18025 }
18033 const slice_len = slice_val.sliceLen(target);18026 const slice_len = slice_val.sliceLen(sema.mod);
18034 const slice_len_s = slice_len + @boolToInt(slice_sent);18027 const slice_len_s = slice_len + @boolToInt(slice_sent);
18035 if (slice_len_s == 0) {18028 if (slice_len_s == 0) {
18036 return sema.fail(block, elem_index_src, "indexing into empty slice", .{});18029 return sema.fail(block, elem_index_src, "indexing into empty slice", .{});
...@@ -18041,7 +18034,7 @@ fn elemPtrSlice(...@@ -18041,7 +18034,7 @@ fn elemPtrSlice(
18041 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";18034 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
18042 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });18035 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
18043 }18036 }
18044 const elem_ptr_val = try slice_val.elemPtr(slice_ty, sema.arena, index, target);18037 const elem_ptr_val = try slice_val.elemPtr(slice_ty, sema.arena, index, sema.mod);
18045 return sema.addConstant(elem_ptr_ty, elem_ptr_val);18038 return sema.addConstant(elem_ptr_ty, elem_ptr_val);
18046 }18039 }
18047 }18040 }
...@@ -18052,7 +18045,7 @@ fn elemPtrSlice(...@@ -18052,7 +18045,7 @@ fn elemPtrSlice(
18052 const len_inst = len: {18045 const len_inst = len: {
18053 if (maybe_undef_slice_val) |slice_val|18046 if (maybe_undef_slice_val) |slice_val|
18054 if (!slice_val.isUndef())18047 if (!slice_val.isUndef())
18055 break :len try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(target));18048 break :len try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(sema.mod));
18056 break :len try block.addTyOp(.slice_len, Type.usize, slice);18049 break :len try block.addTyOp(.slice_len, Type.usize, slice);
18057 };18050 };
18058 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;18051 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
...@@ -18079,7 +18072,7 @@ fn coerce(...@@ -18079,7 +18072,7 @@ fn coerce(
18079 const inst_ty = try sema.resolveTypeFields(block, inst_src, sema.typeOf(inst));18072 const inst_ty = try sema.resolveTypeFields(block, inst_src, sema.typeOf(inst));
18080 const target = sema.mod.getTarget();18073 const target = sema.mod.getTarget();
18081 // If the types are the same, we can return the operand.18074 // If the types are the same, we can return the operand.
18082 if (dest_ty.eql(inst_ty, target))18075 if (dest_ty.eql(inst_ty, sema.mod))
18083 return inst;18076 return inst;
1808418077
18085 const arena = sema.arena;18078 const arena = sema.arena;
...@@ -18185,7 +18178,7 @@ fn coerce(...@@ -18185,7 +18178,7 @@ fn coerce(
18185 // *[N:s]T to [*]T18178 // *[N:s]T to [*]T
18186 if (dest_info.sentinel) |dst_sentinel| {18179 if (dest_info.sentinel) |dst_sentinel| {
18187 if (array_ty.sentinel()) |src_sentinel| {18180 if (array_ty.sentinel()) |src_sentinel| {
18188 if (src_sentinel.eql(dst_sentinel, dst_elem_type, target)) {18181 if (src_sentinel.eql(dst_sentinel, dst_elem_type, sema.mod)) {
18189 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);18182 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
18190 }18183 }
18191 }18184 }
...@@ -18254,7 +18247,7 @@ fn coerce(...@@ -18254,7 +18247,7 @@ fn coerce(
18254 }18247 }
18255 if (inst_info.size == .Slice) {18248 if (inst_info.size == .Slice) {
18256 if (dest_info.sentinel == null or inst_info.sentinel == null or18249 if (dest_info.sentinel == null or inst_info.sentinel == null or
18257 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type, target))18250 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type, sema.mod))
18258 break :p;18251 break :p;
1825918252
18260 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);18253 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
...@@ -18334,7 +18327,7 @@ fn coerce(...@@ -18334,7 +18327,7 @@ fn coerce(
18334 }18327 }
1833518328
18336 if (dest_info.sentinel == null or inst_info.sentinel == null or18329 if (dest_info.sentinel == null or inst_info.sentinel == null or
18337 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type, target))18330 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type, sema.mod))
18338 break :p;18331 break :p;
1833918332
18340 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);18333 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
...@@ -18347,11 +18340,16 @@ fn coerce(...@@ -18347,11 +18340,16 @@ fn coerce(
18347 const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse break :float;18340 const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse break :float;
1834818341
18349 if (val.floatHasFraction()) {18342 if (val.floatHasFraction()) {
18350 return sema.fail(block, inst_src, "fractional component prevents float value {} from coercion to type '{}'", .{ val.fmtValue(inst_ty, target), dest_ty.fmt(target) });18343 return sema.fail(
18344 block,
18345 inst_src,
18346 "fractional component prevents float value {} from coercion to type '{}'",
18347 .{ val.fmtValue(inst_ty, sema.mod), dest_ty.fmt(sema.mod) },
18348 );
18351 }18349 }
18352 const result_val = val.floatToInt(sema.arena, inst_ty, dest_ty, target) catch |err| switch (err) {18350 const result_val = val.floatToInt(sema.arena, inst_ty, dest_ty, target) catch |err| switch (err) {
18353 error.FloatCannotFit => {18351 error.FloatCannotFit => {
18354 return sema.fail(block, inst_src, "integer value {d} cannot be stored in type '{}'", .{ std.math.floor(val.toFloat(f64)), dest_ty.fmt(target) });18352 return sema.fail(block, inst_src, "integer value {d} cannot be stored in type '{}'", .{ std.math.floor(val.toFloat(f64)), dest_ty.fmt(sema.mod) });
18355 },18353 },
18356 else => |e| return e,18354 else => |e| return e,
18357 };18355 };
...@@ -18361,7 +18359,7 @@ fn coerce(...@@ -18361,7 +18359,7 @@ fn coerce(
18361 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {18359 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {
18362 // comptime known integer to other number18360 // comptime known integer to other number
18363 if (!val.intFitsInType(dest_ty, target)) {18361 if (!val.intFitsInType(dest_ty, target)) {
18364 return sema.fail(block, inst_src, "type {} cannot represent integer value {}", .{ dest_ty.fmt(target), val.fmtValue(inst_ty, target) });18362 return sema.fail(block, inst_src, "type {} cannot represent integer value {}", .{ dest_ty.fmt(sema.mod), val.fmtValue(inst_ty, sema.mod) });
18365 }18363 }
18366 return try sema.addConstant(dest_ty, val);18364 return try sema.addConstant(dest_ty, val);
18367 }18365 }
...@@ -18391,12 +18389,12 @@ fn coerce(...@@ -18391,12 +18389,12 @@ fn coerce(
18391 .Float => {18389 .Float => {
18392 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {18390 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {
18393 const result_val = try val.floatCast(sema.arena, dest_ty, target);18391 const result_val = try val.floatCast(sema.arena, dest_ty, target);
18394 if (!val.eql(result_val, dest_ty, target)) {18392 if (!val.eql(result_val, dest_ty, sema.mod)) {
18395 return sema.fail(18393 return sema.fail(
18396 block,18394 block,
18397 inst_src,18395 inst_src,
18398 "type {} cannot represent float value {}",18396 "type {} cannot represent float value {}",
18399 .{ dest_ty.fmt(target), val.fmtValue(inst_ty, target) },18397 .{ dest_ty.fmt(sema.mod), val.fmtValue(inst_ty, sema.mod) },
18400 );18398 );
18401 }18399 }
18402 return try sema.addConstant(dest_ty, result_val);18400 return try sema.addConstant(dest_ty, result_val);
...@@ -18415,12 +18413,12 @@ fn coerce(...@@ -18415,12 +18413,12 @@ fn coerce(
18415 const result_val = try val.intToFloat(sema.arena, inst_ty, dest_ty, target);18413 const result_val = try val.intToFloat(sema.arena, inst_ty, dest_ty, target);
18416 // TODO implement this compile error18414 // TODO implement this compile error
18417 //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty);18415 //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty);
18418 //if (!int_again_val.eql(val, inst_ty, target)) {18416 //if (!int_again_val.eql(val, inst_ty, mod)) {
18419 // return sema.fail(18417 // return sema.fail(
18420 // block,18418 // block,
18421 // inst_src,18419 // inst_src,
18422 // "type {} cannot represent integer value {}",18420 // "type {} cannot represent integer value {}",
18423 // .{ dest_ty.fmt(target), val },18421 // .{ dest_ty.fmt(sema.mod), val },
18424 // );18422 // );
18425 //}18423 //}
18426 return try sema.addConstant(dest_ty, result_val);18424 return try sema.addConstant(dest_ty, result_val);
...@@ -18441,11 +18439,11 @@ fn coerce(...@@ -18441,11 +18439,11 @@ fn coerce(
18441 block,18439 block,
18442 inst_src,18440 inst_src,
18443 "enum '{}' has no field named '{s}'",18441 "enum '{}' has no field named '{s}'",
18444 .{ dest_ty.fmt(target), bytes },18442 .{ dest_ty.fmt(sema.mod), bytes },
18445 );18443 );
18446 errdefer msg.destroy(sema.gpa);18444 errdefer msg.destroy(sema.gpa);
18447 try sema.mod.errNoteNonLazy(18445 try sema.mod.errNoteNonLazy(
18448 dest_ty.declSrcLoc(),18446 dest_ty.declSrcLoc(sema.mod),
18449 msg,18447 msg,
18450 "enum declared here",18448 "enum declared here",
18451 .{},18449 .{},
...@@ -18462,7 +18460,7 @@ fn coerce(...@@ -18462,7 +18460,7 @@ fn coerce(
18462 .Union => blk: {18460 .Union => blk: {
18463 // union to its own tag type18461 // union to its own tag type
18464 const union_tag_ty = inst_ty.unionTagType() orelse break :blk;18462 const union_tag_ty = inst_ty.unionTagType() orelse break :blk;
18465 if (union_tag_ty.eql(dest_ty, target)) {18463 if (union_tag_ty.eql(dest_ty, sema.mod)) {
18466 return sema.unionToTag(block, dest_ty, inst, inst_src);18464 return sema.unionToTag(block, dest_ty, inst, inst_src);
18467 }18465 }
18468 },18466 },
...@@ -18557,7 +18555,7 @@ fn coerce(...@@ -18557,7 +18555,7 @@ fn coerce(
18557 return sema.addConstUndef(dest_ty);18555 return sema.addConstUndef(dest_ty);
18558 }18556 }
1855918557
18560 return sema.fail(block, inst_src, "expected {}, found {}", .{ dest_ty.fmt(target), inst_ty.fmt(target) });18558 return sema.fail(block, inst_src, "expected {}, found {}", .{ dest_ty.fmt(sema.mod), inst_ty.fmt(sema.mod) });
18561}18559}
1856218560
18563const InMemoryCoercionResult = enum {18561const InMemoryCoercionResult = enum {
...@@ -18586,7 +18584,7 @@ fn coerceInMemoryAllowed(...@@ -18586,7 +18584,7 @@ fn coerceInMemoryAllowed(
18586 dest_src: LazySrcLoc,18584 dest_src: LazySrcLoc,
18587 src_src: LazySrcLoc,18585 src_src: LazySrcLoc,
18588) CompileError!InMemoryCoercionResult {18586) CompileError!InMemoryCoercionResult {
18589 if (dest_ty.eql(src_ty, target))18587 if (dest_ty.eql(src_ty, sema.mod))
18590 return .ok;18588 return .ok;
1859118589
18592 // Differently-named integers with the same number of bits.18590 // Differently-named integers with the same number of bits.
...@@ -18650,7 +18648,7 @@ fn coerceInMemoryAllowed(...@@ -18650,7 +18648,7 @@ fn coerceInMemoryAllowed(
18650 }18648 }
18651 const ok_sent = dest_info.sentinel == null or18649 const ok_sent = dest_info.sentinel == null or
18652 (src_info.sentinel != null and18650 (src_info.sentinel != null and
18653 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.elem_type, target));18651 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.elem_type, sema.mod));
18654 if (!ok_sent) {18652 if (!ok_sent) {
18655 return .no_match;18653 return .no_match;
18656 }18654 }
...@@ -18893,7 +18891,7 @@ fn coerceInMemoryAllowedPtrs(...@@ -18893,7 +18891,7 @@ fn coerceInMemoryAllowedPtrs(
1889318891
18894 const ok_sent = dest_info.sentinel == null or src_info.size == .C or18892 const ok_sent = dest_info.sentinel == null or src_info.size == .C or
18895 (src_info.sentinel != null and18893 (src_info.sentinel != null and
18896 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.pointee_type, target));18894 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.pointee_type, sema.mod));
18897 if (!ok_sent) {18895 if (!ok_sent) {
18898 return .no_match;18896 return .no_match;
18899 }18897 }
...@@ -18934,7 +18932,7 @@ fn coerceInMemoryAllowedPtrs(...@@ -18934,7 +18932,7 @@ fn coerceInMemoryAllowedPtrs(
18934 // resolved and we compare the alignment numerically.18932 // resolved and we compare the alignment numerically.
18935 alignment: {18933 alignment: {
18936 if (src_info.@"align" == 0 and dest_info.@"align" == 0 and18934 if (src_info.@"align" == 0 and dest_info.@"align" == 0 and
18937 dest_info.pointee_type.eql(src_info.pointee_type, target))18935 dest_info.pointee_type.eql(src_info.pointee_type, sema.mod))
18938 {18936 {
18939 break :alignment;18937 break :alignment;
18940 }18938 }
...@@ -19089,8 +19087,7 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {...@@ -19089,8 +19087,7 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
19089 // We have a pointer-to-array and a pointer-to-vector. If the elements and19087 // We have a pointer-to-array and a pointer-to-vector. If the elements and
19090 // lengths match, return the result.19088 // lengths match, return the result.
19091 const vector_ty = sema.typeOf(prev_ptr).childType();19089 const vector_ty = sema.typeOf(prev_ptr).childType();
19092 const target = sema.mod.getTarget();19090 if (array_ty.childType().eql(vector_ty.childType(), sema.mod) and
19093 if (array_ty.childType().eql(vector_ty.childType(), target) and
19094 array_ty.arrayLen() == vector_ty.vectorLen())19091 array_ty.arrayLen() == vector_ty.vectorLen())
19095 {19092 {
19096 return prev_ptr;19093 return prev_ptr;
...@@ -19114,8 +19111,8 @@ fn storePtrVal(...@@ -19114,8 +19111,8 @@ fn storePtrVal(
1911419111
19115 const bitcasted_val = try sema.bitCastVal(block, src, operand_val, operand_ty, mut_kit.ty, 0);19112 const bitcasted_val = try sema.bitCastVal(block, src, operand_val, operand_ty, mut_kit.ty, 0);
1911619113
19117 const arena = mut_kit.beginArena(sema.gpa);19114 const arena = mut_kit.beginArena(sema.mod);
19118 defer mut_kit.finishArena();19115 defer mut_kit.finishArena(sema.mod);
1911919116
19120 mut_kit.val.* = try bitcasted_val.copy(arena);19117 mut_kit.val.* = try bitcasted_val.copy(arena);
19121}19118}
...@@ -19126,13 +19123,15 @@ const ComptimePtrMutationKit = struct {...@@ -19126,13 +19123,15 @@ const ComptimePtrMutationKit = struct {
19126 ty: Type,19123 ty: Type,
19127 decl_arena: std.heap.ArenaAllocator = undefined,19124 decl_arena: std.heap.ArenaAllocator = undefined,
1912819125
19129 fn beginArena(self: *ComptimePtrMutationKit, gpa: Allocator) Allocator {19126 fn beginArena(self: *ComptimePtrMutationKit, mod: *Module) Allocator {
19130 self.decl_arena = self.decl_ref_mut.decl.value_arena.?.promote(gpa);19127 const decl = mod.declPtr(self.decl_ref_mut.decl_index);
19128 self.decl_arena = decl.value_arena.?.promote(mod.gpa);
19131 return self.decl_arena.allocator();19129 return self.decl_arena.allocator();
19132 }19130 }
1913319131
19134 fn finishArena(self: *ComptimePtrMutationKit) void {19132 fn finishArena(self: *ComptimePtrMutationKit, mod: *Module) void {
19135 self.decl_ref_mut.decl.value_arena.?.* = self.decl_arena.state;19133 const decl = mod.declPtr(self.decl_ref_mut.decl_index);
19134 decl.value_arena.?.* = self.decl_arena.state;
19136 self.decl_arena = undefined;19135 self.decl_arena = undefined;
19137 }19136 }
19138};19137};
...@@ -19154,10 +19153,11 @@ fn beginComptimePtrMutation(...@@ -19154,10 +19153,11 @@ fn beginComptimePtrMutation(
19154 switch (ptr_val.tag()) {19153 switch (ptr_val.tag()) {
19155 .decl_ref_mut => {19154 .decl_ref_mut => {
19156 const decl_ref_mut = ptr_val.castTag(.decl_ref_mut).?.data;19155 const decl_ref_mut = ptr_val.castTag(.decl_ref_mut).?.data;
19156 const decl = sema.mod.declPtr(decl_ref_mut.decl_index);
19157 return ComptimePtrMutationKit{19157 return ComptimePtrMutationKit{
19158 .decl_ref_mut = decl_ref_mut,19158 .decl_ref_mut = decl_ref_mut,
19159 .val = &decl_ref_mut.decl.val,19159 .val = &decl.val,
19160 .ty = decl_ref_mut.decl.ty,19160 .ty = decl.ty,
19161 };19161 };
19162 },19162 },
19163 .elem_ptr => {19163 .elem_ptr => {
...@@ -19178,8 +19178,8 @@ fn beginComptimePtrMutation(...@@ -19178,8 +19178,8 @@ fn beginComptimePtrMutation(
19178 // An array has been initialized to undefined at comptime and now we19178 // An array has been initialized to undefined at comptime and now we
19179 // are for the first time setting an element. We must change the representation19179 // are for the first time setting an element. We must change the representation
19180 // of the array from `undef` to `array`.19180 // of the array from `undef` to `array`.
19181 const arena = parent.beginArena(sema.gpa);19181 const arena = parent.beginArena(sema.mod);
19182 defer parent.finishArena();19182 defer parent.finishArena(sema.mod);
1918319183
19184 const array_len_including_sentinel =19184 const array_len_including_sentinel =
19185 try sema.usizeCast(block, src, parent.ty.arrayLenIncludingSentinel());19185 try sema.usizeCast(block, src, parent.ty.arrayLenIncludingSentinel());
...@@ -19200,8 +19200,8 @@ fn beginComptimePtrMutation(...@@ -19200,8 +19200,8 @@ fn beginComptimePtrMutation(
19200 // If we wanted to avoid this, there would need to be special detection19200 // If we wanted to avoid this, there would need to be special detection
19201 // elsewhere to identify when writing a value to an array element that is stored19201 // elsewhere to identify when writing a value to an array element that is stored
19202 // using the `bytes` tag, and handle it without making a call to this function.19202 // using the `bytes` tag, and handle it without making a call to this function.
19203 const arena = parent.beginArena(sema.gpa);19203 const arena = parent.beginArena(sema.mod);
19204 defer parent.finishArena();19204 defer parent.finishArena(sema.mod);
1920519205
19206 const bytes = parent.val.castTag(.bytes).?.data;19206 const bytes = parent.val.castTag(.bytes).?.data;
19207 const dest_len = parent.ty.arrayLenIncludingSentinel();19207 const dest_len = parent.ty.arrayLenIncludingSentinel();
...@@ -19229,8 +19229,8 @@ fn beginComptimePtrMutation(...@@ -19229,8 +19229,8 @@ fn beginComptimePtrMutation(
19229 // need to be special detection elsewhere to identify when writing a value to an19229 // need to be special detection elsewhere to identify when writing a value to an
19230 // array element that is stored using the `repeated` tag, and handle it19230 // array element that is stored using the `repeated` tag, and handle it
19231 // without making a call to this function.19231 // without making a call to this function.
19232 const arena = parent.beginArena(sema.gpa);19232 const arena = parent.beginArena(sema.mod);
19233 defer parent.finishArena();19233 defer parent.finishArena(sema.mod);
1923419234
19235 const repeated_val = try parent.val.castTag(.repeated).?.data.copy(arena);19235 const repeated_val = try parent.val.castTag(.repeated).?.data.copy(arena);
19236 const array_len_including_sentinel =19236 const array_len_including_sentinel =
...@@ -19281,8 +19281,8 @@ fn beginComptimePtrMutation(...@@ -19281,8 +19281,8 @@ fn beginComptimePtrMutation(
19281 // A struct or union has been initialized to undefined at comptime and now we19281 // A struct or union has been initialized to undefined at comptime and now we
19282 // are for the first time setting a field. We must change the representation19282 // are for the first time setting a field. We must change the representation
19283 // of the struct/union from `undef` to `struct`/`union`.19283 // of the struct/union from `undef` to `struct`/`union`.
19284 const arena = parent.beginArena(sema.gpa);19284 const arena = parent.beginArena(sema.mod);
19285 defer parent.finishArena();19285 defer parent.finishArena(sema.mod);
1928619286
19287 switch (parent.ty.zigTypeTag()) {19287 switch (parent.ty.zigTypeTag()) {
19288 .Struct => {19288 .Struct => {
...@@ -19322,8 +19322,8 @@ fn beginComptimePtrMutation(...@@ -19322,8 +19322,8 @@ fn beginComptimePtrMutation(
19322 },19322 },
19323 .@"union" => {19323 .@"union" => {
19324 // We need to set the active field of the union.19324 // We need to set the active field of the union.
19325 const arena = parent.beginArena(sema.gpa);19325 const arena = parent.beginArena(sema.mod);
19326 defer parent.finishArena();19326 defer parent.finishArena(sema.mod);
1932719327
19328 const payload = &parent.val.castTag(.@"union").?.data;19328 const payload = &parent.val.castTag(.@"union").?.data;
19329 payload.tag = try Value.Tag.enum_field_index.create(arena, field_index);19329 payload.tag = try Value.Tag.enum_field_index.create(arena, field_index);
...@@ -19347,8 +19347,8 @@ fn beginComptimePtrMutation(...@@ -19347,8 +19347,8 @@ fn beginComptimePtrMutation(
19347 // An error union has been initialized to undefined at comptime and now we19347 // An error union has been initialized to undefined at comptime and now we
19348 // are for the first time setting the payload. We must change the19348 // are for the first time setting the payload. We must change the
19349 // representation of the error union from `undef` to `opt_payload`.19349 // representation of the error union from `undef` to `opt_payload`.
19350 const arena = parent.beginArena(sema.gpa);19350 const arena = parent.beginArena(sema.mod);
19351 defer parent.finishArena();19351 defer parent.finishArena(sema.mod);
1935219352
19353 const payload = try arena.create(Value.Payload.SubValue);19353 const payload = try arena.create(Value.Payload.SubValue);
19354 payload.* = .{19354 payload.* = .{
...@@ -19380,8 +19380,8 @@ fn beginComptimePtrMutation(...@@ -19380,8 +19380,8 @@ fn beginComptimePtrMutation(
19380 // An optional has been initialized to undefined at comptime and now we19380 // An optional has been initialized to undefined at comptime and now we
19381 // are for the first time setting the payload. We must change the19381 // are for the first time setting the payload. We must change the
19382 // representation of the optional from `undef` to `opt_payload`.19382 // representation of the optional from `undef` to `opt_payload`.
19383 const arena = parent.beginArena(sema.gpa);19383 const arena = parent.beginArena(sema.mod);
19384 defer parent.finishArena();19384 defer parent.finishArena(sema.mod);
1938519385
19386 const payload = try arena.create(Value.Payload.SubValue);19386 const payload = try arena.create(Value.Payload.SubValue);
19387 payload.* = .{19387 payload.* = .{
...@@ -19451,12 +19451,13 @@ fn beginComptimePtrLoad(...@@ -19451,12 +19451,13 @@ fn beginComptimePtrLoad(
19451 .decl_ref,19451 .decl_ref,
19452 .decl_ref_mut,19452 .decl_ref_mut,
19453 => blk: {19453 => blk: {
19454 const decl = switch (ptr_val.tag()) {19454 const decl_index = switch (ptr_val.tag()) {
19455 .decl_ref => ptr_val.castTag(.decl_ref).?.data,19455 .decl_ref => ptr_val.castTag(.decl_ref).?.data,
19456 .decl_ref_mut => ptr_val.castTag(.decl_ref_mut).?.data.decl,19456 .decl_ref_mut => ptr_val.castTag(.decl_ref_mut).?.data.decl_index,
19457 else => unreachable,19457 else => unreachable,
19458 };19458 };
19459 const is_mutable = ptr_val.tag() == .decl_ref_mut;19459 const is_mutable = ptr_val.tag() == .decl_ref_mut;
19460 const decl = sema.mod.declPtr(decl_index);
19460 const decl_tv = try decl.typedValue();19461 const decl_tv = try decl.typedValue();
19461 if (decl_tv.val.tag() == .variable) return error.RuntimeLoad;19462 if (decl_tv.val.tag() == .variable) return error.RuntimeLoad;
1946219463
...@@ -19477,7 +19478,9 @@ fn beginComptimePtrLoad(...@@ -19477,7 +19478,9 @@ fn beginComptimePtrLoad(
19477 // This code assumes that elem_ptrs have been "flattened" in order for direct dereference19478 // This code assumes that elem_ptrs have been "flattened" in order for direct dereference
19478 // to succeed, meaning that elem ptrs of the same elem_ty are coalesced. Here we check that19479 // to succeed, meaning that elem ptrs of the same elem_ty are coalesced. Here we check that
19479 // our parent is not an elem_ptr with the same elem_ty, since that would be "unflattened"19480 // our parent is not an elem_ptr with the same elem_ty, since that would be "unflattened"
19480 if (elem_ptr.array_ptr.castTag(.elem_ptr)) |parent_elem_ptr| assert(!(parent_elem_ptr.data.elem_ty.eql(elem_ty, target)));19481 if (elem_ptr.array_ptr.castTag(.elem_ptr)) |parent_elem_ptr| {
19482 assert(!(parent_elem_ptr.data.elem_ty.eql(elem_ty, sema.mod)));
19483 }
1948119484
19482 if (elem_ptr.index != 0) {19485 if (elem_ptr.index != 0) {
19483 if (elem_ty.hasWellDefinedLayout()) {19486 if (elem_ty.hasWellDefinedLayout()) {
...@@ -19510,11 +19513,11 @@ fn beginComptimePtrLoad(...@@ -19510,11 +19513,11 @@ fn beginComptimePtrLoad(
19510 if (maybe_array_ty) |load_ty| {19513 if (maybe_array_ty) |load_ty| {
19511 // It's possible that we're loading a [N]T, in which case we'd like to slice19514 // It's possible that we're loading a [N]T, in which case we'd like to slice
19512 // the pointee array directly from our parent array.19515 // the pointee array directly from our parent array.
19513 if (load_ty.isArrayOrVector() and load_ty.childType().eql(elem_ty, target)) {19516 if (load_ty.isArrayOrVector() and load_ty.childType().eql(elem_ty, sema.mod)) {
19514 const N = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel());19517 const N = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel());
19515 deref.pointee = if (elem_ptr.index + N <= check_len) TypedValue{19518 deref.pointee = if (elem_ptr.index + N <= check_len) TypedValue{
19516 .ty = try Type.array(sema.arena, N, null, elem_ty, target),19519 .ty = try Type.array(sema.arena, N, null, elem_ty, sema.mod),
19517 .val = try array_tv.val.sliceArray(sema.arena, elem_ptr.index, elem_ptr.index + N),19520 .val = try array_tv.val.sliceArray(sema.mod, sema.arena, elem_ptr.index, elem_ptr.index + N),
19518 } else null;19521 } else null;
19519 break :blk deref;19522 break :blk deref;
19520 }19523 }
...@@ -19522,7 +19525,7 @@ fn beginComptimePtrLoad(...@@ -19522,7 +19525,7 @@ fn beginComptimePtrLoad(
1952219525
19523 deref.pointee = if (elem_ptr.index < check_len) TypedValue{19526 deref.pointee = if (elem_ptr.index < check_len) TypedValue{
19524 .ty = elem_ty,19527 .ty = elem_ty,
19525 .val = try array_tv.val.elemValue(sema.arena, elem_ptr.index),19528 .val = try array_tv.val.elemValue(sema.mod, sema.arena, elem_ptr.index),
19526 } else null;19529 } else null;
19527 break :blk deref;19530 break :blk deref;
19528 },19531 },
...@@ -19637,9 +19640,9 @@ fn bitCast(...@@ -19637,9 +19640,9 @@ fn bitCast(
1963719640
19638 if (old_bits != dest_bits) {19641 if (old_bits != dest_bits) {
19639 return sema.fail(block, inst_src, "@bitCast size mismatch: destination type '{}' has {d} bits but source type '{}' has {d} bits", .{19642 return sema.fail(block, inst_src, "@bitCast size mismatch: destination type '{}' has {d} bits but source type '{}' has {d} bits", .{
19640 dest_ty.fmt(target),19643 dest_ty.fmt(sema.mod),
19641 dest_bits,19644 dest_bits,
19642 old_ty.fmt(target),19645 old_ty.fmt(sema.mod),
19643 old_bits,19646 old_bits,
19644 });19647 });
19645 }19648 }
...@@ -19662,7 +19665,7 @@ pub fn bitCastVal(...@@ -19662,7 +19665,7 @@ pub fn bitCastVal(
19662 buffer_offset: usize,19665 buffer_offset: usize,
19663) !Value {19666) !Value {
19664 const target = sema.mod.getTarget();19667 const target = sema.mod.getTarget();
19665 if (old_ty.eql(new_ty, target)) return val;19668 if (old_ty.eql(new_ty, sema.mod)) return val;
1966619669
19667 // For types with well-defined memory layouts, we serialize them a byte buffer,19670 // For types with well-defined memory layouts, we serialize them a byte buffer,
19668 // then deserialize to the new type.19671 // then deserialize to the new type.
...@@ -19718,12 +19721,11 @@ fn coerceEnumToUnion(...@@ -19718,12 +19721,11 @@ fn coerceEnumToUnion(
19718 inst_src: LazySrcLoc,19721 inst_src: LazySrcLoc,
19719) !Air.Inst.Ref {19722) !Air.Inst.Ref {
19720 const inst_ty = sema.typeOf(inst);19723 const inst_ty = sema.typeOf(inst);
19721 const target = sema.mod.getTarget();
1972219724
19723 const tag_ty = union_ty.unionTagType() orelse {19725 const tag_ty = union_ty.unionTagType() orelse {
19724 const msg = msg: {19726 const msg = msg: {
19725 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{19727 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{
19726 union_ty.fmt(target), inst_ty.fmt(target),19728 union_ty.fmt(sema.mod), inst_ty.fmt(sema.mod),
19727 });19729 });
19728 errdefer msg.destroy(sema.gpa);19730 errdefer msg.destroy(sema.gpa);
19729 try sema.errNote(block, union_ty_src, msg, "cannot coerce enum to untagged union", .{});19731 try sema.errNote(block, union_ty_src, msg, "cannot coerce enum to untagged union", .{});
...@@ -19736,10 +19738,10 @@ fn coerceEnumToUnion(...@@ -19736,10 +19738,10 @@ fn coerceEnumToUnion(
19736 const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src);19738 const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src);
19737 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {19739 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {
19738 const union_obj = union_ty.cast(Type.Payload.Union).?.data;19740 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
19739 const field_index = union_obj.tag_ty.enumTagFieldIndex(val, target) orelse {19741 const field_index = union_obj.tag_ty.enumTagFieldIndex(val, sema.mod) orelse {
19740 const msg = msg: {19742 const msg = msg: {
19741 const msg = try sema.errMsg(block, inst_src, "union {} has no tag with value {}", .{19743 const msg = try sema.errMsg(block, inst_src, "union {} has no tag with value {}", .{
19742 union_ty.fmt(target), val.fmtValue(tag_ty, target),19744 union_ty.fmt(sema.mod), val.fmtValue(tag_ty, sema.mod),
19743 });19745 });
19744 errdefer msg.destroy(sema.gpa);19746 errdefer msg.destroy(sema.gpa);
19745 try sema.addDeclaredHereNote(msg, union_ty);19747 try sema.addDeclaredHereNote(msg, union_ty);
...@@ -19753,7 +19755,7 @@ fn coerceEnumToUnion(...@@ -19753,7 +19755,7 @@ fn coerceEnumToUnion(
19753 const msg = msg: {19755 const msg = msg: {
19754 const field_name = union_obj.fields.keys()[field_index];19756 const field_name = union_obj.fields.keys()[field_index];
19755 const msg = try sema.errMsg(block, inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{s}'", .{19757 const msg = try sema.errMsg(block, inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{s}'", .{
19756 inst_ty.fmt(target), union_ty.fmt(target), field_ty.fmt(target), field_name,19758 inst_ty.fmt(sema.mod), union_ty.fmt(sema.mod), field_ty.fmt(sema.mod), field_name,
19757 });19759 });
19758 errdefer msg.destroy(sema.gpa);19760 errdefer msg.destroy(sema.gpa);
1975919761
...@@ -19775,7 +19777,7 @@ fn coerceEnumToUnion(...@@ -19775,7 +19777,7 @@ fn coerceEnumToUnion(
19775 if (tag_ty.isNonexhaustiveEnum()) {19777 if (tag_ty.isNonexhaustiveEnum()) {
19776 const msg = msg: {19778 const msg = msg: {
19777 const msg = try sema.errMsg(block, inst_src, "runtime coercion to union {} from non-exhaustive enum", .{19779 const msg = try sema.errMsg(block, inst_src, "runtime coercion to union {} from non-exhaustive enum", .{
19778 union_ty.fmt(target),19780 union_ty.fmt(sema.mod),
19779 });19781 });
19780 errdefer msg.destroy(sema.gpa);19782 errdefer msg.destroy(sema.gpa);
19781 try sema.addDeclaredHereNote(msg, tag_ty);19783 try sema.addDeclaredHereNote(msg, tag_ty);
...@@ -19795,7 +19797,7 @@ fn coerceEnumToUnion(...@@ -19795,7 +19797,7 @@ fn coerceEnumToUnion(
19795 block,19797 block,
19796 inst_src,19798 inst_src,
19797 "runtime coercion from enum '{}' to union '{}' which has non-void fields",19799 "runtime coercion from enum '{}' to union '{}' which has non-void fields",
19798 .{ tag_ty.fmt(target), union_ty.fmt(target) },19800 .{ tag_ty.fmt(sema.mod), union_ty.fmt(sema.mod) },
19799 );19801 );
19800 errdefer msg.destroy(sema.gpa);19802 errdefer msg.destroy(sema.gpa);
1980119803
...@@ -19804,7 +19806,7 @@ fn coerceEnumToUnion(...@@ -19804,7 +19806,7 @@ fn coerceEnumToUnion(
19804 while (it.next()) |field| {19806 while (it.next()) |field| {
19805 const field_name = field.key_ptr.*;19807 const field_name = field.key_ptr.*;
19806 const field_ty = field.value_ptr.ty;19808 const field_ty = field.value_ptr.ty;
19807 try sema.addFieldErrNote(block, union_ty, field_index, msg, "field '{s}' has type '{}'", .{ field_name, field_ty.fmt(target) });19809 try sema.addFieldErrNote(block, union_ty, field_index, msg, "field '{s}' has type '{}'", .{ field_name, field_ty.fmt(sema.mod) });
19808 field_index += 1;19810 field_index += 1;
19809 }19811 }
19810 try sema.addDeclaredHereNote(msg, union_ty);19812 try sema.addDeclaredHereNote(msg, union_ty);
...@@ -19892,7 +19894,7 @@ fn coerceArrayLike(...@@ -19892,7 +19894,7 @@ fn coerceArrayLike(
19892 if (dest_len != inst_len) {19894 if (dest_len != inst_len) {
19893 const msg = msg: {19895 const msg = msg: {
19894 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{19896 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{
19895 dest_ty.fmt(target), inst_ty.fmt(target),19897 dest_ty.fmt(sema.mod), inst_ty.fmt(sema.mod),
19896 });19898 });
19897 errdefer msg.destroy(sema.gpa);19899 errdefer msg.destroy(sema.gpa);
19898 try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len});19900 try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len});
...@@ -19959,12 +19961,11 @@ fn coerceTupleToArray(...@@ -19959,12 +19961,11 @@ fn coerceTupleToArray(
19959 const inst_ty = sema.typeOf(inst);19961 const inst_ty = sema.typeOf(inst);
19960 const inst_len = inst_ty.arrayLen();19962 const inst_len = inst_ty.arrayLen();
19961 const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen());19963 const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen());
19962 const target = sema.mod.getTarget();
1996319964
19964 if (dest_len != inst_len) {19965 if (dest_len != inst_len) {
19965 const msg = msg: {19966 const msg = msg: {
19966 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{19967 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{
19967 dest_ty.fmt(target), inst_ty.fmt(target),19968 dest_ty.fmt(sema.mod), inst_ty.fmt(sema.mod),
19968 });19969 });
19969 errdefer msg.destroy(sema.gpa);19970 errdefer msg.destroy(sema.gpa);
19970 try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len});19971 try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len});
...@@ -20017,8 +20018,7 @@ fn coerceTupleToSlicePtrs(...@@ -20017,8 +20018,7 @@ fn coerceTupleToSlicePtrs(
20017 const tuple_ty = sema.typeOf(ptr_tuple).childType();20018 const tuple_ty = sema.typeOf(ptr_tuple).childType();
20018 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);20019 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);
20019 const slice_info = slice_ty.ptrInfo().data;20020 const slice_info = slice_ty.ptrInfo().data;
20020 const target = sema.mod.getTarget();20021 const array_ty = try Type.array(sema.arena, tuple_ty.structFieldCount(), slice_info.sentinel, slice_info.pointee_type, sema.mod);
20021 const array_ty = try Type.array(sema.arena, tuple_ty.structFieldCount(), slice_info.sentinel, slice_info.pointee_type, target);
20022 const array_inst = try sema.coerceTupleToArray(block, array_ty, slice_ty_src, tuple, tuple_src);20022 const array_inst = try sema.coerceTupleToArray(block, array_ty, slice_ty_src, tuple, tuple_src);
20023 if (slice_info.@"align" != 0) {20023 if (slice_info.@"align" != 0) {
20024 return sema.fail(block, slice_ty_src, "TODO: override the alignment of the array decl we create here", .{});20024 return sema.fail(block, slice_ty_src, "TODO: override the alignment of the array decl we create here", .{});
...@@ -20141,23 +20141,23 @@ fn analyzeDeclVal(...@@ -20141,23 +20141,23 @@ fn analyzeDeclVal(
20141 sema: *Sema,20141 sema: *Sema,
20142 block: *Block,20142 block: *Block,
20143 src: LazySrcLoc,20143 src: LazySrcLoc,
20144 decl: *Decl,20144 decl_index: Decl.Index,
20145) CompileError!Air.Inst.Ref {20145) CompileError!Air.Inst.Ref {
20146 if (sema.decl_val_table.get(decl)) |result| {20146 if (sema.decl_val_table.get(decl_index)) |result| {
20147 return result;20147 return result;
20148 }20148 }
20149 const decl_ref = try sema.analyzeDeclRef(decl);20149 const decl_ref = try sema.analyzeDeclRef(decl_index);
20150 const result = try sema.analyzeLoad(block, src, decl_ref, src);20150 const result = try sema.analyzeLoad(block, src, decl_ref, src);
20151 if (Air.refToIndex(result)) |index| {20151 if (Air.refToIndex(result)) |index| {
20152 if (sema.air_instructions.items(.tag)[index] == .constant) {20152 if (sema.air_instructions.items(.tag)[index] == .constant) {
20153 try sema.decl_val_table.put(sema.gpa, decl, result);20153 try sema.decl_val_table.put(sema.gpa, decl_index, result);
20154 }20154 }
20155 }20155 }
20156 return result;20156 return result;
20157}20157}
2015820158
20159fn ensureDeclAnalyzed(sema: *Sema, decl: *Decl) CompileError!void {20159fn ensureDeclAnalyzed(sema: *Sema, decl_index: Decl.Index) CompileError!void {
20160 sema.mod.ensureDeclAnalyzed(decl) catch |err| {20160 sema.mod.ensureDeclAnalyzed(decl_index) catch |err| {
20161 if (sema.owner_func) |owner_func| {20161 if (sema.owner_func) |owner_func| {
20162 owner_func.state = .dependency_failure;20162 owner_func.state = .dependency_failure;
20163 } else {20163 } else {
...@@ -20186,7 +20186,7 @@ fn refValue(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type, val: Value) !...@@ -20186,7 +20186,7 @@ fn refValue(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type, val: Value) !
20186 try val.copy(anon_decl.arena()),20186 try val.copy(anon_decl.arena()),
20187 0, // default alignment20187 0, // default alignment
20188 );20188 );
20189 try sema.mod.declareDeclDependency(sema.owner_decl, decl);20189 try sema.mod.declareDeclDependency(sema.owner_decl_index, decl);
20190 return try Value.Tag.decl_ref.create(sema.arena, decl);20190 return try Value.Tag.decl_ref.create(sema.arena, decl);
20191}20191}
2019220192
...@@ -20197,29 +20197,29 @@ fn optRefValue(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type, opt_val: ?...@@ -20197,29 +20197,29 @@ fn optRefValue(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type, opt_val: ?
20197 return result;20197 return result;
20198}20198}
2019920199
20200fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref {20200fn analyzeDeclRef(sema: *Sema, decl_index: Decl.Index) CompileError!Air.Inst.Ref {
20201 try sema.mod.declareDeclDependency(sema.owner_decl, decl);20201 try sema.mod.declareDeclDependency(sema.owner_decl_index, decl_index);
20202 try sema.ensureDeclAnalyzed(decl);20202 try sema.ensureDeclAnalyzed(decl_index);
2020320203
20204 const target = sema.mod.getTarget();20204 const decl = sema.mod.declPtr(decl_index);
20205 const decl_tv = try decl.typedValue();20205 const decl_tv = try decl.typedValue();
20206 if (decl_tv.val.castTag(.variable)) |payload| {20206 if (decl_tv.val.castTag(.variable)) |payload| {
20207 const variable = payload.data;20207 const variable = payload.data;
20208 const ty = try Type.ptr(sema.arena, target, .{20208 const ty = try Type.ptr(sema.arena, sema.mod, .{
20209 .pointee_type = decl_tv.ty,20209 .pointee_type = decl_tv.ty,
20210 .mutable = variable.is_mutable,20210 .mutable = variable.is_mutable,
20211 .@"addrspace" = decl.@"addrspace",20211 .@"addrspace" = decl.@"addrspace",
20212 .@"align" = decl.@"align",20212 .@"align" = decl.@"align",
20213 });20213 });
20214 return sema.addConstant(ty, try Value.Tag.decl_ref.create(sema.arena, decl));20214 return sema.addConstant(ty, try Value.Tag.decl_ref.create(sema.arena, decl_index));
20215 }20215 }
20216 return sema.addConstant(20216 return sema.addConstant(
20217 try Type.ptr(sema.arena, target, .{20217 try Type.ptr(sema.arena, sema.mod, .{
20218 .pointee_type = decl_tv.ty,20218 .pointee_type = decl_tv.ty,
20219 .mutable = false,20219 .mutable = false,
20220 .@"addrspace" = decl.@"addrspace",20220 .@"addrspace" = decl.@"addrspace",
20221 }),20221 }),
20222 try Value.Tag.decl_ref.create(sema.arena, decl),20222 try Value.Tag.decl_ref.create(sema.arena, decl_index),
20223 );20223 );
20224}20224}
2022520225
...@@ -20243,13 +20243,12 @@ fn analyzeRef(...@@ -20243,13 +20243,12 @@ fn analyzeRef(
2024320243
20244 try sema.requireRuntimeBlock(block, src);20244 try sema.requireRuntimeBlock(block, src);
20245 const address_space = target_util.defaultAddressSpace(sema.mod.getTarget(), .local);20245 const address_space = target_util.defaultAddressSpace(sema.mod.getTarget(), .local);
20246 const target = sema.mod.getTarget();20246 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
20247 const ptr_type = try Type.ptr(sema.arena, target, .{
20248 .pointee_type = operand_ty,20247 .pointee_type = operand_ty,
20249 .mutable = false,20248 .mutable = false,
20250 .@"addrspace" = address_space,20249 .@"addrspace" = address_space,
20251 });20250 });
20252 const mut_ptr_type = try Type.ptr(sema.arena, target, .{20251 const mut_ptr_type = try Type.ptr(sema.arena, sema.mod, .{
20253 .pointee_type = operand_ty,20252 .pointee_type = operand_ty,
20254 .@"addrspace" = address_space,20253 .@"addrspace" = address_space,
20255 });20254 });
...@@ -20267,11 +20266,10 @@ fn analyzeLoad(...@@ -20267,11 +20266,10 @@ fn analyzeLoad(
20267 ptr: Air.Inst.Ref,20266 ptr: Air.Inst.Ref,
20268 ptr_src: LazySrcLoc,20267 ptr_src: LazySrcLoc,
20269) CompileError!Air.Inst.Ref {20268) CompileError!Air.Inst.Ref {
20270 const target = sema.mod.getTarget();
20271 const ptr_ty = sema.typeOf(ptr);20269 const ptr_ty = sema.typeOf(ptr);
20272 const elem_ty = switch (ptr_ty.zigTypeTag()) {20270 const elem_ty = switch (ptr_ty.zigTypeTag()) {
20273 .Pointer => ptr_ty.childType(),20271 .Pointer => ptr_ty.childType(),
20274 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(target)}),20272 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(sema.mod)}),
20275 };20273 };
20276 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| {20274 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| {
20277 if (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) |elem_val| {20275 if (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) |elem_val| {
...@@ -20310,8 +20308,7 @@ fn analyzeSliceLen(...@@ -20310,8 +20308,7 @@ fn analyzeSliceLen(
20310 if (slice_val.isUndef()) {20308 if (slice_val.isUndef()) {
20311 return sema.addConstUndef(Type.usize);20309 return sema.addConstUndef(Type.usize);
20312 }20310 }
20313 const target = sema.mod.getTarget();20311 return sema.addIntUnsigned(Type.usize, slice_val.sliceLen(sema.mod));
20314 return sema.addIntUnsigned(Type.usize, slice_val.sliceLen(target));
20315 }20312 }
20316 try sema.requireRuntimeBlock(block, src);20313 try sema.requireRuntimeBlock(block, src);
20317 return block.addTyOp(.slice_len, Type.usize, slice_inst);20314 return block.addTyOp(.slice_len, Type.usize, slice_inst);
...@@ -20417,8 +20414,9 @@ fn analyzeSlice(...@@ -20417,8 +20414,9 @@ fn analyzeSlice(
20417 const target = sema.mod.getTarget();20414 const target = sema.mod.getTarget();
20418 const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag()) {20415 const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag()) {
20419 .Pointer => ptr_ptr_ty.elemType(),20416 .Pointer => ptr_ptr_ty.elemType(),
20420 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty.fmt(target)}),20417 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty.fmt(sema.mod)}),
20421 };20418 };
20419 const mod = sema.mod;
2042220420
20423 var array_ty = ptr_ptr_child_ty;20421 var array_ty = ptr_ptr_child_ty;
20424 var slice_ty = ptr_ptr_ty;20422 var slice_ty = ptr_ptr_ty;
...@@ -20465,7 +20463,7 @@ fn analyzeSlice(...@@ -20465,7 +20463,7 @@ fn analyzeSlice(
20465 elem_ty = ptr_ptr_child_ty.childType();20463 elem_ty = ptr_ptr_child_ty.childType();
20466 },20464 },
20467 },20465 },
20468 else => return sema.fail(block, ptr_src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(target)}),20466 else => return sema.fail(block, ptr_src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(mod)}),
20469 }20467 }
2047020468
20471 const ptr = if (slice_ty.isSlice())20469 const ptr = if (slice_ty.isSlice())
...@@ -20492,7 +20490,7 @@ fn analyzeSlice(...@@ -20492,7 +20490,7 @@ fn analyzeSlice(
20492 sema.arena,20490 sema.arena,
20493 array_ty.arrayLenIncludingSentinel(),20491 array_ty.arrayLenIncludingSentinel(),
20494 );20492 );
20495 if (end_val.compare(.gt, len_s_val, Type.usize, target)) {20493 if (end_val.compare(.gt, len_s_val, Type.usize, mod)) {
20496 const sentinel_label: []const u8 = if (array_ty.sentinel() != null)20494 const sentinel_label: []const u8 = if (array_ty.sentinel() != null)
20497 " +1 (sentinel)"20495 " +1 (sentinel)"
20498 else20496 else
...@@ -20503,8 +20501,8 @@ fn analyzeSlice(...@@ -20503,8 +20501,8 @@ fn analyzeSlice(
20503 end_src,20501 end_src,
20504 "end index {} out of bounds for array of length {}{s}",20502 "end index {} out of bounds for array of length {}{s}",
20505 .{20503 .{
20506 end_val.fmtValue(Type.usize, target),20504 end_val.fmtValue(Type.usize, mod),
20507 len_val.fmtValue(Type.usize, target),20505 len_val.fmtValue(Type.usize, mod),
20508 sentinel_label,20506 sentinel_label,
20509 },20507 },
20510 );20508 );
...@@ -20513,7 +20511,7 @@ fn analyzeSlice(...@@ -20513,7 +20511,7 @@ fn analyzeSlice(
20513 // end_is_len is only true if we are NOT using the sentinel20511 // end_is_len is only true if we are NOT using the sentinel
20514 // length. For sentinel-length, we don't want the type to20512 // length. For sentinel-length, we don't want the type to
20515 // contain the sentinel.20513 // contain the sentinel.
20516 if (end_val.eql(len_val, Type.usize, target)) {20514 if (end_val.eql(len_val, Type.usize, mod)) {
20517 end_is_len = true;20515 end_is_len = true;
20518 }20516 }
20519 }20517 }
...@@ -20529,10 +20527,10 @@ fn analyzeSlice(...@@ -20529,10 +20527,10 @@ fn analyzeSlice(
20529 const has_sentinel = slice_ty.sentinel() != null;20527 const has_sentinel = slice_ty.sentinel() != null;
20530 var int_payload: Value.Payload.U64 = .{20528 var int_payload: Value.Payload.U64 = .{
20531 .base = .{ .tag = .int_u64 },20529 .base = .{ .tag = .int_u64 },
20532 .data = slice_val.sliceLen(target) + @boolToInt(has_sentinel),20530 .data = slice_val.sliceLen(mod) + @boolToInt(has_sentinel),
20533 };20531 };
20534 const slice_len_val = Value.initPayload(&int_payload.base);20532 const slice_len_val = Value.initPayload(&int_payload.base);
20535 if (end_val.compare(.gt, slice_len_val, Type.usize, target)) {20533 if (end_val.compare(.gt, slice_len_val, Type.usize, mod)) {
20536 const sentinel_label: []const u8 = if (has_sentinel)20534 const sentinel_label: []const u8 = if (has_sentinel)
20537 " +1 (sentinel)"20535 " +1 (sentinel)"
20538 else20536 else
...@@ -20543,8 +20541,8 @@ fn analyzeSlice(...@@ -20543,8 +20541,8 @@ fn analyzeSlice(
20543 end_src,20541 end_src,
20544 "end index {} out of bounds for slice of length {d}{s}",20542 "end index {} out of bounds for slice of length {d}{s}",
20545 .{20543 .{
20546 end_val.fmtValue(Type.usize, target),20544 end_val.fmtValue(Type.usize, mod),
20547 slice_val.sliceLen(target),20545 slice_val.sliceLen(mod),
20548 sentinel_label,20546 sentinel_label,
20549 },20547 },
20550 );20548 );
...@@ -20557,7 +20555,7 @@ fn analyzeSlice(...@@ -20557,7 +20555,7 @@ fn analyzeSlice(
20557 int_payload.data -= 1;20555 int_payload.data -= 1;
20558 }20556 }
2055920557
20560 if (end_val.eql(slice_len_val, Type.usize, target)) {20558 if (end_val.eql(slice_len_val, Type.usize, mod)) {
20561 end_is_len = true;20559 end_is_len = true;
20562 }20560 }
20563 }20561 }
...@@ -20590,14 +20588,14 @@ fn analyzeSlice(...@@ -20590,14 +20588,14 @@ fn analyzeSlice(
20590 // requirement: start <= end20588 // requirement: start <= end
20591 if (try sema.resolveDefinedValue(block, src, end)) |end_val| {20589 if (try sema.resolveDefinedValue(block, src, end)) |end_val| {
20592 if (try sema.resolveDefinedValue(block, src, start)) |start_val| {20590 if (try sema.resolveDefinedValue(block, src, start)) |start_val| {
20593 if (start_val.compare(.gt, end_val, Type.usize, target)) {20591 if (start_val.compare(.gt, end_val, Type.usize, mod)) {
20594 return sema.fail(20592 return sema.fail(
20595 block,20593 block,
20596 start_src,20594 start_src,
20597 "start index {} is larger than end index {}",20595 "start index {} is larger than end index {}",
20598 .{20596 .{
20599 start_val.fmtValue(Type.usize, target),20597 start_val.fmtValue(Type.usize, mod),
20600 end_val.fmtValue(Type.usize, target),20598 end_val.fmtValue(Type.usize, mod),
20601 },20599 },
20602 );20600 );
20603 }20601 }
...@@ -20613,8 +20611,8 @@ fn analyzeSlice(...@@ -20613,8 +20611,8 @@ fn analyzeSlice(
20613 if (opt_new_len_val) |new_len_val| {20611 if (opt_new_len_val) |new_len_val| {
20614 const new_len_int = new_len_val.toUnsignedInt(target);20612 const new_len_int = new_len_val.toUnsignedInt(target);
2061520613
20616 const return_ty = try Type.ptr(sema.arena, target, .{20614 const return_ty = try Type.ptr(sema.arena, mod, .{
20617 .pointee_type = try Type.array(sema.arena, new_len_int, sentinel, elem_ty, target),20615 .pointee_type = try Type.array(sema.arena, new_len_int, sentinel, elem_ty, mod),
20618 .sentinel = null,20616 .sentinel = null,
20619 .@"align" = new_ptr_ty_info.@"align",20617 .@"align" = new_ptr_ty_info.@"align",
20620 .@"addrspace" = new_ptr_ty_info.@"addrspace",20618 .@"addrspace" = new_ptr_ty_info.@"addrspace",
...@@ -20641,7 +20639,7 @@ fn analyzeSlice(...@@ -20641,7 +20639,7 @@ fn analyzeSlice(
20641 return sema.fail(block, ptr_src, "non-zero length slice of undefined pointer", .{});20639 return sema.fail(block, ptr_src, "non-zero length slice of undefined pointer", .{});
20642 }20640 }
2064320641
20644 const return_ty = try Type.ptr(sema.arena, target, .{20642 const return_ty = try Type.ptr(sema.arena, mod, .{
20645 .pointee_type = elem_ty,20643 .pointee_type = elem_ty,
20646 .sentinel = sentinel,20644 .sentinel = sentinel,
20647 .@"align" = new_ptr_ty_info.@"align",20645 .@"align" = new_ptr_ty_info.@"align",
...@@ -20667,7 +20665,7 @@ fn analyzeSlice(...@@ -20667,7 +20665,7 @@ fn analyzeSlice(
20667 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {20665 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {
20668 // we don't need to add one for sentinels because the20666 // we don't need to add one for sentinels because the
20669 // underlying value data includes the sentinel20667 // underlying value data includes the sentinel
20670 break :blk try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(target));20668 break :blk try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(mod));
20671 }20669 }
2067220670
20673 const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);20671 const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);
...@@ -20920,7 +20918,6 @@ fn cmpVector(...@@ -20920,7 +20918,6 @@ fn cmpVector(
20920 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);20918 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
2092120919
20922 const result_ty = try Type.vector(sema.arena, lhs_ty.vectorLen(), Type.@"bool");20920 const result_ty = try Type.vector(sema.arena, lhs_ty.vectorLen(), Type.@"bool");
20923 const target = sema.mod.getTarget();
2092420921
20925 const runtime_src: LazySrcLoc = src: {20922 const runtime_src: LazySrcLoc = src: {
20926 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {20923 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {
...@@ -20928,7 +20925,7 @@ fn cmpVector(...@@ -20928,7 +20925,7 @@ fn cmpVector(
20928 if (lhs_val.isUndef() or rhs_val.isUndef()) {20925 if (lhs_val.isUndef() or rhs_val.isUndef()) {
20929 return sema.addConstUndef(result_ty);20926 return sema.addConstUndef(result_ty);
20930 }20927 }
20931 const cmp_val = try lhs_val.compareVector(op, rhs_val, lhs_ty, sema.arena, target);20928 const cmp_val = try lhs_val.compareVector(op, rhs_val, lhs_ty, sema.arena, sema.mod);
20932 return sema.addConstant(result_ty, cmp_val);20929 return sema.addConstant(result_ty, cmp_val);
20933 } else {20930 } else {
20934 break :src rhs_src;20931 break :src rhs_src;
...@@ -21080,7 +21077,7 @@ fn resolvePeerTypes(...@@ -21080,7 +21077,7 @@ fn resolvePeerTypes(
21080 const candidate_ty_tag = try candidate_ty.zigTypeTagOrPoison();21077 const candidate_ty_tag = try candidate_ty.zigTypeTagOrPoison();
21081 const chosen_ty_tag = try chosen_ty.zigTypeTagOrPoison();21078 const chosen_ty_tag = try chosen_ty.zigTypeTagOrPoison();
2108221079
21083 if (candidate_ty.eql(chosen_ty, target))21080 if (candidate_ty.eql(chosen_ty, sema.mod))
21084 continue;21081 continue;
2108521082
21086 switch (candidate_ty_tag) {21083 switch (candidate_ty_tag) {
...@@ -21496,27 +21493,27 @@ fn resolvePeerTypes(...@@ -21496,27 +21493,27 @@ fn resolvePeerTypes(
21496 // the source locations.21493 // the source locations.
21497 const chosen_src = candidate_srcs.resolve(21494 const chosen_src = candidate_srcs.resolve(
21498 sema.gpa,21495 sema.gpa,
21499 block.src_decl,21496 sema.mod.declPtr(block.src_decl),
21500 chosen_i,21497 chosen_i,
21501 );21498 );
21502 const candidate_src = candidate_srcs.resolve(21499 const candidate_src = candidate_srcs.resolve(
21503 sema.gpa,21500 sema.gpa,
21504 block.src_decl,21501 sema.mod.declPtr(block.src_decl),
21505 candidate_i + 1,21502 candidate_i + 1,
21506 );21503 );
2150721504
21508 const msg = msg: {21505 const msg = msg: {
21509 const msg = try sema.errMsg(block, src, "incompatible types: '{}' and '{}'", .{21506 const msg = try sema.errMsg(block, src, "incompatible types: '{}' and '{}'", .{
21510 chosen_ty.fmt(target),21507 chosen_ty.fmt(sema.mod),
21511 candidate_ty.fmt(target),21508 candidate_ty.fmt(sema.mod),
21512 });21509 });
21513 errdefer msg.destroy(sema.gpa);21510 errdefer msg.destroy(sema.gpa);
2151421511
21515 if (chosen_src) |src_loc|21512 if (chosen_src) |src_loc|
21516 try sema.errNote(block, src_loc, msg, "type '{}' here", .{chosen_ty.fmt(target)});21513 try sema.errNote(block, src_loc, msg, "type '{}' here", .{chosen_ty.fmt(sema.mod)});
2151721514
21518 if (candidate_src) |src_loc|21515 if (candidate_src) |src_loc|
21519 try sema.errNote(block, src_loc, msg, "type '{}' here", .{candidate_ty.fmt(target)});21516 try sema.errNote(block, src_loc, msg, "type '{}' here", .{candidate_ty.fmt(sema.mod)});
2152021517
21521 break :msg msg;21518 break :msg msg;
21522 };21519 };
...@@ -21538,13 +21535,13 @@ fn resolvePeerTypes(...@@ -21538,13 +21535,13 @@ fn resolvePeerTypes(
21538 else => unreachable,21535 else => unreachable,
21539 };21536 };
2154021537
21541 const new_ptr_ty = try Type.ptr(sema.arena, target, info.data);21538 const new_ptr_ty = try Type.ptr(sema.arena, sema.mod, info.data);
21542 const opt_ptr_ty = if (any_are_null)21539 const opt_ptr_ty = if (any_are_null)
21543 try Type.optional(sema.arena, new_ptr_ty)21540 try Type.optional(sema.arena, new_ptr_ty)
21544 else21541 else
21545 new_ptr_ty;21542 new_ptr_ty;
21546 const set_ty = err_set_ty orelse return opt_ptr_ty;21543 const set_ty = err_set_ty orelse return opt_ptr_ty;
21547 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, target);21544 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, sema.mod);
21548 }21545 }
2154921546
21550 if (seen_const) {21547 if (seen_const) {
...@@ -21554,24 +21551,24 @@ fn resolvePeerTypes(...@@ -21554,24 +21551,24 @@ fn resolvePeerTypes(
21554 const ptr_ty = chosen_ty.errorUnionPayload();21551 const ptr_ty = chosen_ty.errorUnionPayload();
21555 var info = ptr_ty.ptrInfo();21552 var info = ptr_ty.ptrInfo();
21556 info.data.mutable = false;21553 info.data.mutable = false;
21557 const new_ptr_ty = try Type.ptr(sema.arena, target, info.data);21554 const new_ptr_ty = try Type.ptr(sema.arena, sema.mod, info.data);
21558 const opt_ptr_ty = if (any_are_null)21555 const opt_ptr_ty = if (any_are_null)
21559 try Type.optional(sema.arena, new_ptr_ty)21556 try Type.optional(sema.arena, new_ptr_ty)
21560 else21557 else
21561 new_ptr_ty;21558 new_ptr_ty;
21562 const set_ty = err_set_ty orelse chosen_ty.errorUnionSet();21559 const set_ty = err_set_ty orelse chosen_ty.errorUnionSet();
21563 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, target);21560 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, sema.mod);
21564 },21561 },
21565 .Pointer => {21562 .Pointer => {
21566 var info = chosen_ty.ptrInfo();21563 var info = chosen_ty.ptrInfo();
21567 info.data.mutable = false;21564 info.data.mutable = false;
21568 const new_ptr_ty = try Type.ptr(sema.arena, target, info.data);21565 const new_ptr_ty = try Type.ptr(sema.arena, sema.mod, info.data);
21569 const opt_ptr_ty = if (any_are_null)21566 const opt_ptr_ty = if (any_are_null)
21570 try Type.optional(sema.arena, new_ptr_ty)21567 try Type.optional(sema.arena, new_ptr_ty)
21571 else21568 else
21572 new_ptr_ty;21569 new_ptr_ty;
21573 const set_ty = err_set_ty orelse return opt_ptr_ty;21570 const set_ty = err_set_ty orelse return opt_ptr_ty;
21574 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, target);21571 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, sema.mod);
21575 },21572 },
21576 else => return chosen_ty,21573 else => return chosen_ty,
21577 }21574 }
...@@ -21583,16 +21580,16 @@ fn resolvePeerTypes(...@@ -21583,16 +21580,16 @@ fn resolvePeerTypes(
21583 else => try Type.optional(sema.arena, chosen_ty),21580 else => try Type.optional(sema.arena, chosen_ty),
21584 };21581 };
21585 const set_ty = err_set_ty orelse return opt_ty;21582 const set_ty = err_set_ty orelse return opt_ty;
21586 return try Type.errorUnion(sema.arena, set_ty, opt_ty, target);21583 return try Type.errorUnion(sema.arena, set_ty, opt_ty, sema.mod);
21587 }21584 }
2158821585
21589 if (err_set_ty) |ty| switch (chosen_ty.zigTypeTag()) {21586 if (err_set_ty) |ty| switch (chosen_ty.zigTypeTag()) {
21590 .ErrorSet => return ty,21587 .ErrorSet => return ty,
21591 .ErrorUnion => {21588 .ErrorUnion => {
21592 const payload_ty = chosen_ty.errorUnionPayload();21589 const payload_ty = chosen_ty.errorUnionPayload();
21593 return try Type.errorUnion(sema.arena, ty, payload_ty, target);21590 return try Type.errorUnion(sema.arena, ty, payload_ty, sema.mod);
21594 },21591 },
21595 else => return try Type.errorUnion(sema.arena, ty, chosen_ty, target),21592 else => return try Type.errorUnion(sema.arena, ty, chosen_ty, sema.mod),
21596 };21593 };
2159721594
21598 return chosen_ty;21595 return chosen_ty;
...@@ -21670,12 +21667,11 @@ fn resolveStructLayout(...@@ -21670,12 +21667,11 @@ fn resolveStructLayout(
21670) CompileError!void {21667) CompileError!void {
21671 const resolved_ty = try sema.resolveTypeFields(block, src, ty);21668 const resolved_ty = try sema.resolveTypeFields(block, src, ty);
21672 if (resolved_ty.castTag(.@"struct")) |payload| {21669 if (resolved_ty.castTag(.@"struct")) |payload| {
21673 const target = sema.mod.getTarget();
21674 const struct_obj = payload.data;21670 const struct_obj = payload.data;
21675 switch (struct_obj.status) {21671 switch (struct_obj.status) {
21676 .none, .have_field_types => {},21672 .none, .have_field_types => {},
21677 .field_types_wip, .layout_wip => {21673 .field_types_wip, .layout_wip => {
21678 return sema.fail(block, src, "struct {} depends on itself", .{ty.fmt(target)});21674 return sema.fail(block, src, "struct {} depends on itself", .{ty.fmt(sema.mod)});
21679 },21675 },
21680 .have_layout, .fully_resolved_wip, .fully_resolved => return,21676 .have_layout, .fully_resolved_wip, .fully_resolved => return,
21681 }21677 }
...@@ -21703,11 +21699,10 @@ fn resolveUnionLayout(...@@ -21703,11 +21699,10 @@ fn resolveUnionLayout(
21703) CompileError!void {21699) CompileError!void {
21704 const resolved_ty = try sema.resolveTypeFields(block, src, ty);21700 const resolved_ty = try sema.resolveTypeFields(block, src, ty);
21705 const union_obj = resolved_ty.cast(Type.Payload.Union).?.data;21701 const union_obj = resolved_ty.cast(Type.Payload.Union).?.data;
21706 const target = sema.mod.getTarget();
21707 switch (union_obj.status) {21702 switch (union_obj.status) {
21708 .none, .have_field_types => {},21703 .none, .have_field_types => {},
21709 .field_types_wip, .layout_wip => {21704 .field_types_wip, .layout_wip => {
21710 return sema.fail(block, src, "union {} depends on itself", .{ty.fmt(target)});21705 return sema.fail(block, src, "union {} depends on itself", .{ty.fmt(sema.mod)});
21711 },21706 },
21712 .have_layout, .fully_resolved_wip, .fully_resolved => return,21707 .have_layout, .fully_resolved_wip, .fully_resolved => return,
21713 }21708 }
...@@ -21774,10 +21769,6 @@ fn resolveStructFully(...@@ -21774,10 +21769,6 @@ fn resolveStructFully(
21774 .fully_resolved_wip, .fully_resolved => return,21769 .fully_resolved_wip, .fully_resolved => return,
21775 }21770 }
2177621771
21777 log.debug("resolveStructFully {*} ('{s}')", .{
21778 struct_obj.owner_decl, struct_obj.owner_decl.name,
21779 });
21780
21781 {21772 {
21782 // After we have resolve struct layout we have to go over the fields again to21773 // After we have resolve struct layout we have to go over the fields again to
21783 // make sure pointer fields get their child types resolved as well.21774 // make sure pointer fields get their child types resolved as well.
...@@ -21866,11 +21857,10 @@ fn resolveTypeFieldsStruct(...@@ -21866,11 +21857,10 @@ fn resolveTypeFieldsStruct(
21866 ty: Type,21857 ty: Type,
21867 struct_obj: *Module.Struct,21858 struct_obj: *Module.Struct,
21868) CompileError!void {21859) CompileError!void {
21869 const target = sema.mod.getTarget();
21870 switch (struct_obj.status) {21860 switch (struct_obj.status) {
21871 .none => {},21861 .none => {},
21872 .field_types_wip => {21862 .field_types_wip => {
21873 return sema.fail(block, src, "struct {} depends on itself", .{ty.fmt(target)});21863 return sema.fail(block, src, "struct {} depends on itself", .{ty.fmt(sema.mod)});
21874 },21864 },
21875 .have_field_types,21865 .have_field_types,
21876 .have_layout,21866 .have_layout,
...@@ -21897,11 +21887,10 @@ fn resolveTypeFieldsUnion(...@@ -21897,11 +21887,10 @@ fn resolveTypeFieldsUnion(
21897 ty: Type,21887 ty: Type,
21898 union_obj: *Module.Union,21888 union_obj: *Module.Union,
21899) CompileError!void {21889) CompileError!void {
21900 const target = sema.mod.getTarget();
21901 switch (union_obj.status) {21890 switch (union_obj.status) {
21902 .none => {},21891 .none => {},
21903 .field_types_wip => {21892 .field_types_wip => {
21904 return sema.fail(block, src, "union {} depends on itself", .{ty.fmt(target)});21893 return sema.fail(block, src, "union {} depends on itself", .{ty.fmt(sema.mod)});
21905 },21894 },
21906 .have_field_types,21895 .have_field_types,
21907 .have_layout,21896 .have_layout,
...@@ -21945,7 +21934,8 @@ fn resolveInferredErrorSet(...@@ -21945,7 +21934,8 @@ fn resolveInferredErrorSet(
21945 // `*Module.Fn`. Not only is the function not relevant to the inferred error set21934 // `*Module.Fn`. Not only is the function not relevant to the inferred error set
21946 // in this case, it may be a generic function which would cause an assertion failure21935 // in this case, it may be a generic function which would cause an assertion failure
21947 // if we called `ensureFuncBodyAnalyzed` on it here.21936 // if we called `ensureFuncBodyAnalyzed` on it here.
21948 if (ies.func.owner_decl.ty.fnInfo().return_type.errorUnionSet().castTag(.error_set_inferred).?.data == ies) {21937 const ies_func_owner_decl = sema.mod.declPtr(ies.func.owner_decl);
21938 if (ies_func_owner_decl.ty.fnInfo().return_type.errorUnionSet().castTag(.error_set_inferred).?.data == ies) {
21949 // In this case we are dealing with the actual InferredErrorSet object that21939 // In this case we are dealing with the actual InferredErrorSet object that
21950 // corresponds to the function, not one created to track an inline/comptime call.21940 // corresponds to the function, not one created to track an inline/comptime call.
21951 try sema.ensureFuncBodyAnalyzed(ies.func);21941 try sema.ensureFuncBodyAnalyzed(ies.func);
...@@ -21986,7 +21976,7 @@ fn semaStructFields(...@@ -21986,7 +21976,7 @@ fn semaStructFields(
21986 defer tracy.end();21976 defer tracy.end();
2198721977
21988 const gpa = mod.gpa;21978 const gpa = mod.gpa;
21989 const decl = struct_obj.owner_decl;21979 const decl_index = struct_obj.owner_decl;
21990 const zir = struct_obj.namespace.file_scope.zir;21980 const zir = struct_obj.namespace.file_scope.zir;
21991 const extended = zir.instructions.items(.data)[struct_obj.zir_index].extended;21981 const extended = zir.instructions.items(.data)[struct_obj.zir_index].extended;
21992 assert(extended.opcode == .struct_decl);21982 assert(extended.opcode == .struct_decl);
...@@ -22026,6 +22016,7 @@ fn semaStructFields(...@@ -22026,6 +22016,7 @@ fn semaStructFields(
22026 }22016 }
22027 extra_index += body.len;22017 extra_index += body.len;
2202822018
22019 const decl = mod.declPtr(decl_index);
22029 var decl_arena = decl.value_arena.?.promote(gpa);22020 var decl_arena = decl.value_arena.?.promote(gpa);
22030 defer decl.value_arena.?.* = decl_arena.state;22021 defer decl.value_arena.?.* = decl_arena.state;
22031 const decl_arena_allocator = decl_arena.allocator();22022 const decl_arena_allocator = decl_arena.allocator();
...@@ -22040,6 +22031,7 @@ fn semaStructFields(...@@ -22040,6 +22031,7 @@ fn semaStructFields(
22040 .perm_arena = decl_arena_allocator,22031 .perm_arena = decl_arena_allocator,
22041 .code = zir,22032 .code = zir,
22042 .owner_decl = decl,22033 .owner_decl = decl,
22034 .owner_decl_index = decl_index,
22043 .func = null,22035 .func = null,
22044 .fn_ret_ty = Type.void,22036 .fn_ret_ty = Type.void,
22045 .owner_func = null,22037 .owner_func = null,
...@@ -22052,7 +22044,7 @@ fn semaStructFields(...@@ -22052,7 +22044,7 @@ fn semaStructFields(
22052 var block_scope: Block = .{22044 var block_scope: Block = .{
22053 .parent = null,22045 .parent = null,
22054 .sema = &sema,22046 .sema = &sema,
22055 .src_decl = decl,22047 .src_decl = decl_index,
22056 .namespace = &struct_obj.namespace,22048 .namespace = &struct_obj.namespace,
22057 .wip_capture_scope = wip_captures.scope,22049 .wip_capture_scope = wip_captures.scope,
22058 .instructions = .{},22050 .instructions = .{},
...@@ -22171,7 +22163,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil...@@ -22171,7 +22163,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
22171 defer tracy.end();22163 defer tracy.end();
2217222164
22173 const gpa = mod.gpa;22165 const gpa = mod.gpa;
22174 const decl = union_obj.owner_decl;22166 const decl_index = union_obj.owner_decl;
22175 const zir = union_obj.namespace.file_scope.zir;22167 const zir = union_obj.namespace.file_scope.zir;
22176 const extended = zir.instructions.items(.data)[union_obj.zir_index].extended;22168 const extended = zir.instructions.items(.data)[union_obj.zir_index].extended;
22177 assert(extended.opcode == .union_decl);22169 assert(extended.opcode == .union_decl);
...@@ -22217,8 +22209,10 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil...@@ -22217,8 +22209,10 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
22217 }22209 }
22218 extra_index += body.len;22210 extra_index += body.len;
2221922211
22220 var decl_arena = union_obj.owner_decl.value_arena.?.promote(gpa);22212 const decl = mod.declPtr(decl_index);
22221 defer union_obj.owner_decl.value_arena.?.* = decl_arena.state;22213
22214 var decl_arena = decl.value_arena.?.promote(gpa);
22215 defer decl.value_arena.?.* = decl_arena.state;
22222 const decl_arena_allocator = decl_arena.allocator();22216 const decl_arena_allocator = decl_arena.allocator();
2222322217
22224 var analysis_arena = std.heap.ArenaAllocator.init(gpa);22218 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
...@@ -22231,6 +22225,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil...@@ -22231,6 +22225,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
22231 .perm_arena = decl_arena_allocator,22225 .perm_arena = decl_arena_allocator,
22232 .code = zir,22226 .code = zir,
22233 .owner_decl = decl,22227 .owner_decl = decl,
22228 .owner_decl_index = decl_index,
22234 .func = null,22229 .func = null,
22235 .fn_ret_ty = Type.void,22230 .fn_ret_ty = Type.void,
22236 .owner_func = null,22231 .owner_func = null,
...@@ -22243,7 +22238,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil...@@ -22243,7 +22238,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
22243 var block_scope: Block = .{22238 var block_scope: Block = .{
22244 .parent = null,22239 .parent = null,
22245 .sema = &sema,22240 .sema = &sema,
22246 .src_decl = decl,22241 .src_decl = decl_index,
22247 .namespace = &union_obj.namespace,22242 .namespace = &union_obj.namespace,
22248 .wip_capture_scope = wip_captures.scope,22243 .wip_capture_scope = wip_captures.scope,
22249 .instructions = .{},22244 .instructions = .{},
...@@ -22353,7 +22348,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil...@@ -22353,7 +22348,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
22353 const copied_val = try val.copy(decl_arena_allocator);22348 const copied_val = try val.copy(decl_arena_allocator);
22354 map.putAssumeCapacityContext(copied_val, {}, .{22349 map.putAssumeCapacityContext(copied_val, {}, .{
22355 .ty = int_tag_ty,22350 .ty = int_tag_ty,
22356 .target = target,22351 .mod = mod,
22357 });22352 });
22358 } else {22353 } else {
22359 const val = if (last_tag_val) |val|22354 const val = if (last_tag_val) |val|
...@@ -22365,7 +22360,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil...@@ -22365,7 +22360,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
22365 const copied_val = try val.copy(decl_arena_allocator);22360 const copied_val = try val.copy(decl_arena_allocator);
22366 map.putAssumeCapacityContext(copied_val, {}, .{22361 map.putAssumeCapacityContext(copied_val, {}, .{
22367 .ty = int_tag_ty,22362 .ty = int_tag_ty,
22368 .target = target,22363 .mod = mod,
22369 });22364 });
22370 }22365 }
22371 }22366 }
...@@ -22411,7 +22406,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil...@@ -22411,7 +22406,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
22411 const enum_has_field = names.orderedRemove(field_name);22406 const enum_has_field = names.orderedRemove(field_name);
22412 if (!enum_has_field) {22407 if (!enum_has_field) {
22413 const msg = msg: {22408 const msg = msg: {
22414 const msg = try sema.errMsg(block, src, "enum '{}' has no field named '{s}'", .{ union_obj.tag_ty.fmt(target), field_name });22409 const msg = try sema.errMsg(block, src, "enum '{}' has no field named '{s}'", .{ union_obj.tag_ty.fmt(sema.mod), field_name });
22415 errdefer msg.destroy(sema.gpa);22410 errdefer msg.destroy(sema.gpa);
22416 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);22411 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
22417 break :msg msg;22412 break :msg msg;
...@@ -22475,15 +22470,16 @@ fn generateUnionTagTypeNumbered(...@@ -22475,15 +22470,16 @@ fn generateUnionTagTypeNumbered(
22475 const enum_ty = Type.initPayload(&enum_ty_payload.base);22470 const enum_ty = Type.initPayload(&enum_ty_payload.base);
22476 const enum_val = try Value.Tag.ty.create(new_decl_arena_allocator, enum_ty);22471 const enum_val = try Value.Tag.ty.create(new_decl_arena_allocator, enum_ty);
22477 // TODO better type name22472 // TODO better type name
22478 const new_decl = try mod.createAnonymousDecl(block, .{22473 const new_decl_index = try mod.createAnonymousDecl(block, .{
22479 .ty = Type.type,22474 .ty = Type.type,
22480 .val = enum_val,22475 .val = enum_val,
22481 });22476 });
22477 const new_decl = mod.declPtr(new_decl_index);
22482 new_decl.owns_tv = true;22478 new_decl.owns_tv = true;
22483 errdefer mod.abortAnonDecl(new_decl);22479 errdefer mod.abortAnonDecl(new_decl_index);
2248422480
22485 enum_obj.* = .{22481 enum_obj.* = .{
22486 .owner_decl = new_decl,22482 .owner_decl = new_decl_index,
22487 .tag_ty = int_ty,22483 .tag_ty = int_ty,
22488 .fields = .{},22484 .fields = .{},
22489 .values = .{},22485 .values = .{},
...@@ -22493,7 +22489,7 @@ fn generateUnionTagTypeNumbered(...@@ -22493,7 +22489,7 @@ fn generateUnionTagTypeNumbered(
22493 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);22489 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
22494 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{22490 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{
22495 .ty = int_ty,22491 .ty = int_ty,
22496 .target = sema.mod.getTarget(),22492 .mod = mod,
22497 });22493 });
22498 try new_decl.finalizeNewArena(&new_decl_arena);22494 try new_decl.finalizeNewArena(&new_decl_arena);
22499 return enum_ty;22495 return enum_ty;
...@@ -22515,15 +22511,16 @@ fn generateUnionTagTypeSimple(sema: *Sema, block: *Block, fields_len: usize) !Ty...@@ -22515,15 +22511,16 @@ fn generateUnionTagTypeSimple(sema: *Sema, block: *Block, fields_len: usize) !Ty
22515 const enum_ty = Type.initPayload(&enum_ty_payload.base);22511 const enum_ty = Type.initPayload(&enum_ty_payload.base);
22516 const enum_val = try Value.Tag.ty.create(new_decl_arena_allocator, enum_ty);22512 const enum_val = try Value.Tag.ty.create(new_decl_arena_allocator, enum_ty);
22517 // TODO better type name22513 // TODO better type name
22518 const new_decl = try mod.createAnonymousDecl(block, .{22514 const new_decl_index = try mod.createAnonymousDecl(block, .{
22519 .ty = Type.type,22515 .ty = Type.type,
22520 .val = enum_val,22516 .val = enum_val,
22521 });22517 });
22518 const new_decl = mod.declPtr(new_decl_index);
22522 new_decl.owns_tv = true;22519 new_decl.owns_tv = true;
22523 errdefer mod.abortAnonDecl(new_decl);22520 errdefer mod.abortAnonDecl(new_decl_index);
2252422521
22525 enum_obj.* = .{22522 enum_obj.* = .{
22526 .owner_decl = new_decl,22523 .owner_decl = new_decl_index,
22527 .fields = .{},22524 .fields = .{},
22528 .node_offset = 0,22525 .node_offset = 0,
22529 };22526 };
...@@ -22545,7 +22542,7 @@ fn getBuiltin(...@@ -22545,7 +22542,7 @@ fn getBuiltin(
22545 const opt_builtin_inst = try sema.namespaceLookupRef(22542 const opt_builtin_inst = try sema.namespaceLookupRef(
22546 block,22543 block,
22547 src,22544 src,
22548 std_file.root_decl.?.src_namespace,22545 mod.declPtr(std_file.root_decl.unwrap().?).src_namespace,
22549 "builtin",22546 "builtin",
22550 );22547 );
22551 const builtin_inst = try sema.analyzeLoad(block, src, opt_builtin_inst.?, src);22548 const builtin_inst = try sema.analyzeLoad(block, src, opt_builtin_inst.?, src);
...@@ -22984,8 +22981,7 @@ fn analyzeComptimeAlloc(...@@ -22984,8 +22981,7 @@ fn analyzeComptimeAlloc(
22984 // Needed to make an anon decl with type `var_type` (the `finish()` call below).22981 // Needed to make an anon decl with type `var_type` (the `finish()` call below).
22985 _ = try sema.typeHasOnePossibleValue(block, src, var_type);22982 _ = try sema.typeHasOnePossibleValue(block, src, var_type);
2298622983
22987 const target = sema.mod.getTarget();22984 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
22988 const ptr_type = try Type.ptr(sema.arena, target, .{
22989 .pointee_type = var_type,22985 .pointee_type = var_type,
22990 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant),22986 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant),
22991 .@"align" = alignment,22987 .@"align" = alignment,
...@@ -22994,7 +22990,7 @@ fn analyzeComptimeAlloc(...@@ -22994,7 +22990,7 @@ fn analyzeComptimeAlloc(
22994 var anon_decl = try block.startAnonDecl(src);22990 var anon_decl = try block.startAnonDecl(src);
22995 defer anon_decl.deinit();22991 defer anon_decl.deinit();
2299622992
22997 const decl = try anon_decl.finish(22993 const decl_index = try anon_decl.finish(
22998 try var_type.copy(anon_decl.arena()),22994 try var_type.copy(anon_decl.arena()),
22999 // There will be stores before the first load, but they may be to sub-elements or22995 // There will be stores before the first load, but they may be to sub-elements or
23000 // sub-fields. So we need to initialize with undef to allow the mechanism to expand22996 // sub-fields. So we need to initialize with undef to allow the mechanism to expand
...@@ -23002,12 +22998,13 @@ fn analyzeComptimeAlloc(...@@ -23002,12 +22998,13 @@ fn analyzeComptimeAlloc(
23002 Value.undef,22998 Value.undef,
23003 alignment,22999 alignment,
23004 );23000 );
23001 const decl = sema.mod.declPtr(decl_index);
23005 decl.@"align" = alignment;23002 decl.@"align" = alignment;
2300623003
23007 try sema.mod.declareDeclDependency(sema.owner_decl, decl);23004 try sema.mod.declareDeclDependency(sema.owner_decl_index, decl_index);
23008 return sema.addConstant(ptr_type, try Value.Tag.decl_ref_mut.create(sema.arena, .{23005 return sema.addConstant(ptr_type, try Value.Tag.decl_ref_mut.create(sema.arena, .{
23009 .runtime_index = block.runtime_index,23006 .runtime_index = block.runtime_index,
23010 .decl = decl,23007 .decl_index = decl_index,
23011 }));23008 }));
23012}23009}
2301323010
...@@ -23099,7 +23096,7 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr...@@ -23099,7 +23096,7 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr
23099 // The type is not in-memory coercible or the direct dereference failed, so it must23096 // The type is not in-memory coercible or the direct dereference failed, so it must
23100 // be bitcast according to the pointer type we are performing the load through.23097 // be bitcast according to the pointer type we are performing the load through.
23101 if (!load_ty.hasWellDefinedLayout())23098 if (!load_ty.hasWellDefinedLayout())
23102 return sema.fail(block, src, "comptime dereference requires {} to have a well-defined layout, but it does not.", .{load_ty.fmt(target)});23099 return sema.fail(block, src, "comptime dereference requires {} to have a well-defined layout, but it does not.", .{load_ty.fmt(sema.mod)});
2310323100
23104 const load_sz = try sema.typeAbiSize(block, src, load_ty);23101 const load_sz = try sema.typeAbiSize(block, src, load_ty);
2310523102
...@@ -23114,11 +23111,11 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr...@@ -23114,11 +23111,11 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr
23114 if (deref.ty_without_well_defined_layout) |bad_ty| {23111 if (deref.ty_without_well_defined_layout) |bad_ty| {
23115 // We got no parent for bit-casting, or the parent we got was too small. Either way, the problem23112 // We got no parent for bit-casting, or the parent we got was too small. Either way, the problem
23116 // is that some type we encountered when de-referencing does not have a well-defined layout.23113 // is that some type we encountered when de-referencing does not have a well-defined layout.
23117 return sema.fail(block, src, "comptime dereference requires {} to have a well-defined layout, but it does not.", .{bad_ty.fmt(target)});23114 return sema.fail(block, src, "comptime dereference requires {} to have a well-defined layout, but it does not.", .{bad_ty.fmt(sema.mod)});
23118 } else {23115 } else {
23119 // If all encountered types had well-defined layouts, the parent is the root decl and it just23116 // If all encountered types had well-defined layouts, the parent is the root decl and it just
23120 // wasn't big enough for the load.23117 // wasn't big enough for the load.
23121 return sema.fail(block, src, "dereference of {} exceeds bounds of containing decl of type {}", .{ ptr_ty.fmt(target), deref.parent.?.tv.ty.fmt(target) });23118 return sema.fail(block, src, "dereference of {} exceeds bounds of containing decl of type {}", .{ ptr_ty.fmt(sema.mod), deref.parent.?.tv.ty.fmt(sema.mod) });
23122 }23119 }
23123}23120}
2312423121
...@@ -23484,9 +23481,8 @@ fn anonStructFieldIndex(...@@ -23484,9 +23481,8 @@ fn anonStructFieldIndex(
23484 return @intCast(u32, i);23481 return @intCast(u32, i);
23485 }23482 }
23486 }23483 }
23487 const target = sema.mod.getTarget();
23488 return sema.fail(block, field_src, "anonymous struct {} has no such field '{s}'", .{23484 return sema.fail(block, field_src, "anonymous struct {} has no such field '{s}'", .{
23489 struct_ty.fmt(target), field_name,23485 struct_ty.fmt(sema.mod), field_name,
23490 });23486 });
23491}23487}
2349223488
src/TypedValue.zig+29-23
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1const std = @import("std");1const std = @import("std");
2const Type = @import("type.zig").Type;2const Type = @import("type.zig").Type;
3const Value = @import("value.zig").Value;3const Value = @import("value.zig").Value;
4const Module = @import("Module.zig");
4const Allocator = std.mem.Allocator;5const Allocator = std.mem.Allocator;
5const TypedValue = @This();6const TypedValue = @This();
6const Target = std.Target;7const Target = std.Target;
...@@ -31,13 +32,13 @@ pub fn copy(self: TypedValue, arena: Allocator) error{OutOfMemory}!TypedValue {...@@ -31,13 +32,13 @@ pub fn copy(self: TypedValue, arena: Allocator) error{OutOfMemory}!TypedValue {
31 };32 };
32}33}
3334
34pub fn eql(a: TypedValue, b: TypedValue, target: std.Target) bool {35pub fn eql(a: TypedValue, b: TypedValue, mod: *Module) bool {
35 if (!a.ty.eql(b.ty, target)) return false;36 if (!a.ty.eql(b.ty, mod)) return false;
36 return a.val.eql(b.val, a.ty, target);37 return a.val.eql(b.val, a.ty, mod);
37}38}
3839
39pub fn hash(tv: TypedValue, hasher: *std.hash.Wyhash, target: std.Target) void {40pub fn hash(tv: TypedValue, hasher: *std.hash.Wyhash, mod: *Module) void {
40 return tv.val.hash(tv.ty, hasher, target);41 return tv.val.hash(tv.ty, hasher, mod);
41}42}
4243
43pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value {44pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value {
...@@ -48,7 +49,7 @@ const max_aggregate_items = 100;...@@ -48,7 +49,7 @@ const max_aggregate_items = 100;
4849
49const FormatContext = struct {50const FormatContext = struct {
50 tv: TypedValue,51 tv: TypedValue,
51 target: Target,52 mod: *Module,
52};53};
5354
54pub fn format(55pub fn format(
...@@ -59,7 +60,7 @@ pub fn format(...@@ -59,7 +60,7 @@ pub fn format(
59) !void {60) !void {
60 _ = options;61 _ = options;
61 comptime std.debug.assert(fmt.len == 0);62 comptime std.debug.assert(fmt.len == 0);
62 return ctx.tv.print(writer, 3, ctx.target);63 return ctx.tv.print(writer, 3, ctx.mod);
63}64}
6465
65/// Prints the Value according to the Type, not according to the Value Tag.66/// Prints the Value according to the Type, not according to the Value Tag.
...@@ -67,8 +68,9 @@ pub fn print(...@@ -67,8 +68,9 @@ pub fn print(
67 tv: TypedValue,68 tv: TypedValue,
68 writer: anytype,69 writer: anytype,
69 level: u8,70 level: u8,
70 target: std.Target,71 mod: *Module,
71) @TypeOf(writer).Error!void {72) @TypeOf(writer).Error!void {
73 const target = mod.getTarget();
72 var val = tv.val;74 var val = tv.val;
73 var ty = tv.ty;75 var ty = tv.ty;
74 while (true) switch (val.tag()) {76 while (true) switch (val.tag()) {
...@@ -156,7 +158,7 @@ pub fn print(...@@ -156,7 +158,7 @@ pub fn print(
156 try print(.{158 try print(.{
157 .ty = fields[i].ty,159 .ty = fields[i].ty,
158 .val = vals[i],160 .val = vals[i],
159 }, writer, level - 1, target);161 }, writer, level - 1, mod);
160 }162 }
161 return writer.writeAll(" }");163 return writer.writeAll(" }");
162 } else {164 } else {
...@@ -170,7 +172,7 @@ pub fn print(...@@ -170,7 +172,7 @@ pub fn print(
170 try print(.{172 try print(.{
171 .ty = elem_ty,173 .ty = elem_ty,
172 .val = vals[i],174 .val = vals[i],
173 }, writer, level - 1, target);175 }, writer, level - 1, mod);
174 }176 }
175 return writer.writeAll(" }");177 return writer.writeAll(" }");
176 }178 }
...@@ -185,12 +187,12 @@ pub fn print(...@@ -185,12 +187,12 @@ pub fn print(
185 try print(.{187 try print(.{
186 .ty = ty.unionTagType().?,188 .ty = ty.unionTagType().?,
187 .val = union_val.tag,189 .val = union_val.tag,
188 }, writer, level - 1, target);190 }, writer, level - 1, mod);
189 try writer.writeAll(" = ");191 try writer.writeAll(" = ");
190 try print(.{192 try print(.{
191 .ty = ty.unionFieldType(union_val.tag, target),193 .ty = ty.unionFieldType(union_val.tag, mod),
192 .val = union_val.val,194 .val = union_val.val,
193 }, writer, level - 1, target);195 }, writer, level - 1, mod);
194196
195 return writer.writeAll(" }");197 return writer.writeAll(" }");
196 },198 },
...@@ -205,7 +207,7 @@ pub fn print(...@@ -205,7 +207,7 @@ pub fn print(
205 },207 },
206 .bool_true => return writer.writeAll("true"),208 .bool_true => return writer.writeAll("true"),
207 .bool_false => return writer.writeAll("false"),209 .bool_false => return writer.writeAll("false"),
208 .ty => return val.castTag(.ty).?.data.print(writer, target),210 .ty => return val.castTag(.ty).?.data.print(writer, mod),
209 .int_type => {211 .int_type => {
210 const int_type = val.castTag(.int_type).?.data;212 const int_type = val.castTag(.int_type).?.data;
211 return writer.print("{s}{d}", .{213 return writer.print("{s}{d}", .{
...@@ -222,28 +224,32 @@ pub fn print(...@@ -222,28 +224,32 @@ pub fn print(
222 const x = sub_ty.abiAlignment(target);224 const x = sub_ty.abiAlignment(target);
223 return writer.print("{d}", .{x});225 return writer.print("{d}", .{x});
224 },226 },
225 .function => return writer.print("(function '{s}')", .{val.castTag(.function).?.data.owner_decl.name}),227 .function => return writer.print("(function '{s}')", .{
228 mod.declPtr(val.castTag(.function).?.data.owner_decl).name,
229 }),
226 .extern_fn => return writer.writeAll("(extern function)"),230 .extern_fn => return writer.writeAll("(extern function)"),
227 .variable => return writer.writeAll("(variable)"),231 .variable => return writer.writeAll("(variable)"),
228 .decl_ref_mut => {232 .decl_ref_mut => {
229 const decl = val.castTag(.decl_ref_mut).?.data.decl;233 const decl_index = val.castTag(.decl_ref_mut).?.data.decl_index;
234 const decl = mod.declPtr(decl_index);
230 if (level == 0) {235 if (level == 0) {
231 return writer.print("(decl ref mut '{s}')", .{decl.name});236 return writer.print("(decl ref mut '{s}')", .{decl.name});
232 }237 }
233 return print(.{238 return print(.{
234 .ty = decl.ty,239 .ty = decl.ty,
235 .val = decl.val,240 .val = decl.val,
236 }, writer, level - 1, target);241 }, writer, level - 1, mod);
237 },242 },
238 .decl_ref => {243 .decl_ref => {
239 const decl = val.castTag(.decl_ref).?.data;244 const decl_index = val.castTag(.decl_ref).?.data;
245 const decl = mod.declPtr(decl_index);
240 if (level == 0) {246 if (level == 0) {
241 return writer.print("(decl ref '{s}')", .{decl.name});247 return writer.print("(decl ref '{s}')", .{decl.name});
242 }248 }
243 return print(.{249 return print(.{
244 .ty = decl.ty,250 .ty = decl.ty,
245 .val = decl.val,251 .val = decl.val,
246 }, writer, level - 1, target);252 }, writer, level - 1, mod);
247 },253 },
248 .elem_ptr => {254 .elem_ptr => {
249 const elem_ptr = val.castTag(.elem_ptr).?.data;255 const elem_ptr = val.castTag(.elem_ptr).?.data;
...@@ -251,7 +257,7 @@ pub fn print(...@@ -251,7 +257,7 @@ pub fn print(
251 try print(.{257 try print(.{
252 .ty = elem_ptr.elem_ty,258 .ty = elem_ptr.elem_ty,
253 .val = elem_ptr.array_ptr,259 .val = elem_ptr.array_ptr,
254 }, writer, level - 1, target);260 }, writer, level - 1, mod);
255 return writer.print("[{}]", .{elem_ptr.index});261 return writer.print("[{}]", .{elem_ptr.index});
256 },262 },
257 .field_ptr => {263 .field_ptr => {
...@@ -260,7 +266,7 @@ pub fn print(...@@ -260,7 +266,7 @@ pub fn print(
260 try print(.{266 try print(.{
261 .ty = field_ptr.container_ty,267 .ty = field_ptr.container_ty,
262 .val = field_ptr.container_ptr,268 .val = field_ptr.container_ptr,
263 }, writer, level - 1, target);269 }, writer, level - 1, mod);
264270
265 if (field_ptr.container_ty.zigTypeTag() == .Struct) {271 if (field_ptr.container_ty.zigTypeTag() == .Struct) {
266 const field_name = field_ptr.container_ty.structFields().keys()[field_ptr.field_index];272 const field_name = field_ptr.container_ty.structFields().keys()[field_ptr.field_index];
...@@ -288,7 +294,7 @@ pub fn print(...@@ -288,7 +294,7 @@ pub fn print(
288 };294 };
289 while (i < max_aggregate_items) : (i += 1) {295 while (i < max_aggregate_items) : (i += 1) {
290 if (i != 0) try writer.writeAll(", ");296 if (i != 0) try writer.writeAll(", ");
291 try print(elem_tv, writer, level - 1, target);297 try print(elem_tv, writer, level - 1, mod);
292 }298 }
293 return writer.writeAll(" }");299 return writer.writeAll(" }");
294 },300 },
...@@ -300,7 +306,7 @@ pub fn print(...@@ -300,7 +306,7 @@ pub fn print(
300 try print(.{306 try print(.{
301 .ty = ty.elemType2(),307 .ty = ty.elemType2(),
302 .val = ty.sentinel().?,308 .val = ty.sentinel().?,
303 }, writer, level - 1, target);309 }, writer, level - 1, mod);
304 return writer.writeAll(" }");310 return writer.writeAll(" }");
305 },311 },
306 .slice => return writer.writeAll("(slice)"),312 .slice => return writer.writeAll("(slice)"),
src/arch/aarch64/CodeGen.zig+34-24
...@@ -237,8 +237,10 @@ pub fn generate(...@@ -237,8 +237,10 @@ pub fn generate(
237 @panic("Attempted to compile for architecture that was disabled by build configuration");237 @panic("Attempted to compile for architecture that was disabled by build configuration");
238 }238 }
239239
240 assert(module_fn.owner_decl.has_tv);240 const mod = bin_file.options.module.?;
241 const fn_type = module_fn.owner_decl.ty;241 const fn_owner_decl = mod.declPtr(module_fn.owner_decl);
242 assert(fn_owner_decl.has_tv);
243 const fn_type = fn_owner_decl.ty;
242244
243 var branch_stack = std.ArrayList(Branch).init(bin_file.allocator);245 var branch_stack = std.ArrayList(Branch).init(bin_file.allocator);
244 defer {246 defer {
...@@ -819,9 +821,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -819,9 +821,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
819 return @as(u32, 0);821 return @as(u32, 0);
820 }822 }
821823
822 const target = self.target.*;
823 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {824 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
824 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});825 const mod = self.bin_file.options.module.?;
826 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
825 };827 };
826 // TODO swap this for inst.ty.ptrAlign828 // TODO swap this for inst.ty.ptrAlign
827 const abi_align = elem_ty.abiAlignment(self.target.*);829 const abi_align = elem_ty.abiAlignment(self.target.*);
...@@ -830,9 +832,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -830,9 +832,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
830832
831fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {833fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
832 const elem_ty = self.air.typeOfIndex(inst);834 const elem_ty = self.air.typeOfIndex(inst);
833 const target = self.target.*;
834 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {835 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
835 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});836 const mod = self.bin_file.options.module.?;
837 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
836 };838 };
837 const abi_align = elem_ty.abiAlignment(self.target.*);839 const abi_align = elem_ty.abiAlignment(self.target.*);
838 if (abi_align > self.stack_align)840 if (abi_align > self.stack_align)
...@@ -1422,7 +1424,7 @@ fn binOp(...@@ -1422,7 +1424,7 @@ fn binOp(
1422 lhs_ty: Type,1424 lhs_ty: Type,
1423 rhs_ty: Type,1425 rhs_ty: Type,
1424) InnerError!MCValue {1426) InnerError!MCValue {
1425 const target = self.target.*;1427 const mod = self.bin_file.options.module.?;
1426 switch (tag) {1428 switch (tag) {
1427 .add,1429 .add,
1428 .sub,1430 .sub,
...@@ -1432,7 +1434,7 @@ fn binOp(...@@ -1432,7 +1434,7 @@ fn binOp(
1432 .Float => return self.fail("TODO binary operations on floats", .{}),1434 .Float => return self.fail("TODO binary operations on floats", .{}),
1433 .Vector => return self.fail("TODO binary operations on vectors", .{}),1435 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1434 .Int => {1436 .Int => {
1435 assert(lhs_ty.eql(rhs_ty, target));1437 assert(lhs_ty.eql(rhs_ty, mod));
1436 const int_info = lhs_ty.intInfo(self.target.*);1438 const int_info = lhs_ty.intInfo(self.target.*);
1437 if (int_info.bits <= 64) {1439 if (int_info.bits <= 64) {
1438 // Only say yes if the operation is1440 // Only say yes if the operation is
...@@ -1483,7 +1485,7 @@ fn binOp(...@@ -1483,7 +1485,7 @@ fn binOp(
1483 switch (lhs_ty.zigTypeTag()) {1485 switch (lhs_ty.zigTypeTag()) {
1484 .Vector => return self.fail("TODO binary operations on vectors", .{}),1486 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1485 .Int => {1487 .Int => {
1486 assert(lhs_ty.eql(rhs_ty, target));1488 assert(lhs_ty.eql(rhs_ty, mod));
1487 const int_info = lhs_ty.intInfo(self.target.*);1489 const int_info = lhs_ty.intInfo(self.target.*);
1488 if (int_info.bits <= 64) {1490 if (int_info.bits <= 64) {
1489 // TODO add optimisations for multiplication1491 // TODO add optimisations for multiplication
...@@ -1534,7 +1536,7 @@ fn binOp(...@@ -1534,7 +1536,7 @@ fn binOp(
1534 switch (lhs_ty.zigTypeTag()) {1536 switch (lhs_ty.zigTypeTag()) {
1535 .Vector => return self.fail("TODO binary operations on vectors", .{}),1537 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1536 .Int => {1538 .Int => {
1537 assert(lhs_ty.eql(rhs_ty, target));1539 assert(lhs_ty.eql(rhs_ty, mod));
1538 const int_info = lhs_ty.intInfo(self.target.*);1540 const int_info = lhs_ty.intInfo(self.target.*);
1539 if (int_info.bits <= 64) {1541 if (int_info.bits <= 64) {
1540 // TODO implement bitwise operations with immediates1542 // TODO implement bitwise operations with immediates
...@@ -2425,12 +2427,12 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -2425,12 +2427,12 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
2425 const ty = self.air.typeOfIndex(inst);2427 const ty = self.air.typeOfIndex(inst);
24262428
2427 const result = self.args[arg_index];2429 const result = self.args[arg_index];
2428 const target = self.target.*;
2429 const mcv = switch (result) {2430 const mcv = switch (result) {
2430 // Copy registers to the stack2431 // Copy registers to the stack
2431 .register => |reg| blk: {2432 .register => |reg| blk: {
2433 const mod = self.bin_file.options.module.?;
2432 const abi_size = math.cast(u32, ty.abiSize(self.target.*)) catch {2434 const abi_size = math.cast(u32, ty.abiSize(self.target.*)) catch {
2433 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(target)});2435 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)});
2434 };2436 };
2435 const abi_align = ty.abiAlignment(self.target.*);2437 const abi_align = ty.abiAlignment(self.target.*);
2436 const stack_offset = try self.allocMem(inst, abi_size, abi_align);2438 const stack_offset = try self.allocMem(inst, abi_size, abi_align);
...@@ -2537,17 +2539,19 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -2537,17 +2539,19 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
25372539
2538 // Due to incremental compilation, how function calls are generated depends2540 // Due to incremental compilation, how function calls are generated depends
2539 // on linking.2541 // on linking.
2542 const mod = self.bin_file.options.module.?;
2540 if (self.air.value(callee)) |func_value| {2543 if (self.air.value(callee)) |func_value| {
2541 if (self.bin_file.tag == link.File.Elf.base_tag or self.bin_file.tag == link.File.Coff.base_tag) {2544 if (self.bin_file.tag == link.File.Elf.base_tag or self.bin_file.tag == link.File.Coff.base_tag) {
2542 if (func_value.castTag(.function)) |func_payload| {2545 if (func_value.castTag(.function)) |func_payload| {
2543 const func = func_payload.data;2546 const func = func_payload.data;
2544 const ptr_bits = self.target.cpu.arch.ptrBitWidth();2547 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
2545 const ptr_bytes: u64 = @divExact(ptr_bits, 8);2548 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
2549 const fn_owner_decl = mod.declPtr(func.owner_decl);
2546 const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: {2550 const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: {
2547 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];2551 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
2548 break :blk @intCast(u32, got.p_vaddr + func.owner_decl.link.elf.offset_table_index * ptr_bytes);2552 break :blk @intCast(u32, got.p_vaddr + fn_owner_decl.link.elf.offset_table_index * ptr_bytes);
2549 } else if (self.bin_file.cast(link.File.Coff)) |coff_file|2553 } else if (self.bin_file.cast(link.File.Coff)) |coff_file|
2550 coff_file.offset_table_virtual_address + func.owner_decl.link.coff.offset_table_index * ptr_bytes2554 coff_file.offset_table_virtual_address + fn_owner_decl.link.coff.offset_table_index * ptr_bytes
2551 else2555 else
2552 unreachable;2556 unreachable;
25532557
...@@ -2565,8 +2569,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -2565,8 +2569,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
2565 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {2569 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
2566 if (func_value.castTag(.function)) |func_payload| {2570 if (func_value.castTag(.function)) |func_payload| {
2567 const func = func_payload.data;2571 const func = func_payload.data;
2572 const fn_owner_decl = mod.declPtr(func.owner_decl);
2568 try self.genSetReg(Type.initTag(.u64), .x30, .{2573 try self.genSetReg(Type.initTag(.u64), .x30, .{
2569 .got_load = func.owner_decl.link.macho.local_sym_index,2574 .got_load = fn_owner_decl.link.macho.local_sym_index,
2570 });2575 });
2571 // blr x302576 // blr x30
2572 _ = try self.addInst(.{2577 _ = try self.addInst(.{
...@@ -2575,7 +2580,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -2575,7 +2580,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
2575 });2580 });
2576 } else if (func_value.castTag(.extern_fn)) |func_payload| {2581 } else if (func_value.castTag(.extern_fn)) |func_payload| {
2577 const extern_fn = func_payload.data;2582 const extern_fn = func_payload.data;
2578 const decl_name = extern_fn.owner_decl.name;2583 const decl_name = mod.declPtr(extern_fn.owner_decl).name;
2579 if (extern_fn.lib_name) |lib_name| {2584 if (extern_fn.lib_name) |lib_name| {
2580 log.debug("TODO enforce that '{s}' is expected in '{s}' library", .{2585 log.debug("TODO enforce that '{s}' is expected in '{s}' library", .{
2581 decl_name,2586 decl_name,
...@@ -2588,7 +2593,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -2588,7 +2593,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
2588 .tag = .call_extern,2593 .tag = .call_extern,
2589 .data = .{2594 .data = .{
2590 .extern_fn = .{2595 .extern_fn = .{
2591 .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index,2596 .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.local_sym_index,
2592 .sym_name = n_strx,2597 .sym_name = n_strx,
2593 },2598 },
2594 },2599 },
...@@ -2602,7 +2607,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -2602,7 +2607,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
2602 const ptr_bits = self.target.cpu.arch.ptrBitWidth();2607 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
2603 const ptr_bytes: u64 = @divExact(ptr_bits, 8);2608 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
2604 const got_addr = p9.bases.data;2609 const got_addr = p9.bases.data;
2605 const got_index = func_payload.data.owner_decl.link.plan9.got_index.?;2610 const got_index = mod.declPtr(func_payload.data.owner_decl).link.plan9.got_index.?;
2606 const fn_got_addr = got_addr + got_index * ptr_bytes;2611 const fn_got_addr = got_addr + got_index * ptr_bytes;
26072612
2608 try self.genSetReg(Type.initTag(.usize), .x30, .{ .memory = fn_got_addr });2613 try self.genSetReg(Type.initTag(.usize), .x30, .{ .memory = fn_got_addr });
...@@ -3478,12 +3483,13 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -3478,12 +3483,13 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
3478 .direct_load => .load_memory_ptr_direct,3483 .direct_load => .load_memory_ptr_direct,
3479 else => unreachable,3484 else => unreachable,
3480 };3485 };
3486 const mod = self.bin_file.options.module.?;
3481 _ = try self.addInst(.{3487 _ = try self.addInst(.{
3482 .tag = tag,3488 .tag = tag,
3483 .data = .{3489 .data = .{
3484 .payload = try self.addExtra(Mir.LoadMemoryPie{3490 .payload = try self.addExtra(Mir.LoadMemoryPie{
3485 .register = @enumToInt(src_reg),3491 .register = @enumToInt(src_reg),
3486 .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index,3492 .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.local_sym_index,
3487 .sym_index = sym_index,3493 .sym_index = sym_index,
3488 }),3494 }),
3489 },3495 },
...@@ -3597,12 +3603,13 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -3597,12 +3603,13 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
3597 .direct_load => .load_memory_direct,3603 .direct_load => .load_memory_direct,
3598 else => unreachable,3604 else => unreachable,
3599 };3605 };
3606 const mod = self.bin_file.options.module.?;
3600 _ = try self.addInst(.{3607 _ = try self.addInst(.{
3601 .tag = tag,3608 .tag = tag,
3602 .data = .{3609 .data = .{
3603 .payload = try self.addExtra(Mir.LoadMemoryPie{3610 .payload = try self.addExtra(Mir.LoadMemoryPie{
3604 .register = @enumToInt(reg),3611 .register = @enumToInt(reg),
3605 .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index,3612 .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.local_sym_index,
3606 .sym_index = sym_index,3613 .sym_index = sym_index,
3607 }),3614 }),
3608 },3615 },
...@@ -3860,7 +3867,7 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {...@@ -3860,7 +3867,7 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
3860 }3867 }
3861}3868}
38623869
3863fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCValue {3870fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) InnerError!MCValue {
3864 const ptr_bits = self.target.cpu.arch.ptrBitWidth();3871 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
3865 const ptr_bytes: u64 = @divExact(ptr_bits, 8);3872 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
38663873
...@@ -3872,7 +3879,10 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa...@@ -3872,7 +3879,10 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa
3872 }3879 }
3873 }3880 }
38743881
3875 decl.alive = true;3882 const mod = self.bin_file.options.module.?;
3883 const decl = mod.declPtr(decl_index);
3884 mod.markDeclAlive(decl);
3885
3876 if (self.bin_file.cast(link.File.Elf)) |elf_file| {3886 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
3877 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];3887 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
3878 const got_addr = got.p_vaddr + decl.link.elf.offset_table_index * ptr_bytes;3888 const got_addr = got.p_vaddr + decl.link.elf.offset_table_index * ptr_bytes;
...@@ -3886,7 +3896,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa...@@ -3886,7 +3896,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa
3886 const got_addr = coff_file.offset_table_virtual_address + decl.link.coff.offset_table_index * ptr_bytes;3896 const got_addr = coff_file.offset_table_virtual_address + decl.link.coff.offset_table_index * ptr_bytes;
3887 return MCValue{ .memory = got_addr };3897 return MCValue{ .memory = got_addr };
3888 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {3898 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
3889 try p9.seeDecl(decl);3899 try p9.seeDecl(decl_index);
3890 const got_addr = p9.bases.data + decl.link.plan9.got_index.? * ptr_bytes;3900 const got_addr = p9.bases.data + decl.link.plan9.got_index.? * ptr_bytes;
3891 return MCValue{ .memory = got_addr };3901 return MCValue{ .memory = got_addr };
3892 } else {3902 } else {
...@@ -3922,7 +3932,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -3922,7 +3932,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
3922 return self.lowerDeclRef(typed_value, payload.data);3932 return self.lowerDeclRef(typed_value, payload.data);
3923 }3933 }
3924 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {3934 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {
3925 return self.lowerDeclRef(typed_value, payload.data.decl);3935 return self.lowerDeclRef(typed_value, payload.data.decl_index);
3926 }3936 }
3927 const target = self.target.*;3937 const target = self.target.*;
39283938
src/arch/arm/CodeGen.zig+33-20
...@@ -271,8 +271,10 @@ pub fn generate(...@@ -271,8 +271,10 @@ pub fn generate(
271 @panic("Attempted to compile for architecture that was disabled by build configuration");271 @panic("Attempted to compile for architecture that was disabled by build configuration");
272 }272 }
273273
274 assert(module_fn.owner_decl.has_tv);274 const mod = bin_file.options.module.?;
275 const fn_type = module_fn.owner_decl.ty;275 const fn_owner_decl = mod.declPtr(module_fn.owner_decl);
276 assert(fn_owner_decl.has_tv);
277 const fn_type = fn_owner_decl.ty;
276278
277 var branch_stack = std.ArrayList(Branch).init(bin_file.allocator);279 var branch_stack = std.ArrayList(Branch).init(bin_file.allocator);
278 defer {280 defer {
...@@ -838,9 +840,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -838,9 +840,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
838 return @as(u32, 0);840 return @as(u32, 0);
839 }841 }
840842
841 const target = self.target.*;
842 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {843 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
843 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});844 const mod = self.bin_file.options.module.?;
845 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
844 };846 };
845 // TODO swap this for inst.ty.ptrAlign847 // TODO swap this for inst.ty.ptrAlign
846 const abi_align = elem_ty.abiAlignment(self.target.*);848 const abi_align = elem_ty.abiAlignment(self.target.*);
...@@ -849,9 +851,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -849,9 +851,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
849851
850fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {852fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
851 const elem_ty = self.air.typeOfIndex(inst);853 const elem_ty = self.air.typeOfIndex(inst);
852 const target = self.target.*;
853 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {854 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
854 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});855 const mod = self.bin_file.options.module.?;
856 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
855 };857 };
856 const abi_align = elem_ty.abiAlignment(self.target.*);858 const abi_align = elem_ty.abiAlignment(self.target.*);
857 if (abi_align > self.stack_align)859 if (abi_align > self.stack_align)
...@@ -1204,7 +1206,8 @@ fn minMax(...@@ -1204,7 +1206,8 @@ fn minMax(
1204 .Float => return self.fail("TODO ARM min/max on floats", .{}),1206 .Float => return self.fail("TODO ARM min/max on floats", .{}),
1205 .Vector => return self.fail("TODO ARM min/max on vectors", .{}),1207 .Vector => return self.fail("TODO ARM min/max on vectors", .{}),
1206 .Int => {1208 .Int => {
1207 assert(lhs_ty.eql(rhs_ty, self.target.*));1209 const mod = self.bin_file.options.module.?;
1210 assert(lhs_ty.eql(rhs_ty, mod));
1208 const int_info = lhs_ty.intInfo(self.target.*);1211 const int_info = lhs_ty.intInfo(self.target.*);
1209 if (int_info.bits <= 32) {1212 if (int_info.bits <= 32) {
1210 const lhs_is_register = lhs == .register;1213 const lhs_is_register = lhs == .register;
...@@ -1372,7 +1375,8 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1372,7 +1375,8 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
1372 switch (lhs_ty.zigTypeTag()) {1375 switch (lhs_ty.zigTypeTag()) {
1373 .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}),1376 .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}),
1374 .Int => {1377 .Int => {
1375 assert(lhs_ty.eql(rhs_ty, self.target.*));1378 const mod = self.bin_file.options.module.?;
1379 assert(lhs_ty.eql(rhs_ty, mod));
1376 const int_info = lhs_ty.intInfo(self.target.*);1380 const int_info = lhs_ty.intInfo(self.target.*);
1377 if (int_info.bits < 32) {1381 if (int_info.bits < 32) {
1378 const stack_offset = try self.allocMem(inst, tuple_size, tuple_align);1382 const stack_offset = try self.allocMem(inst, tuple_size, tuple_align);
...@@ -1472,7 +1476,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1472,7 +1476,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1472 switch (lhs_ty.zigTypeTag()) {1476 switch (lhs_ty.zigTypeTag()) {
1473 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),1477 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),
1474 .Int => {1478 .Int => {
1475 assert(lhs_ty.eql(rhs_ty, self.target.*));1479 const mod = self.bin_file.options.module.?;
1480 assert(lhs_ty.eql(rhs_ty, mod));
1476 const int_info = lhs_ty.intInfo(self.target.*);1481 const int_info = lhs_ty.intInfo(self.target.*);
1477 if (int_info.bits <= 16) {1482 if (int_info.bits <= 16) {
1478 const stack_offset = try self.allocMem(inst, tuple_size, tuple_align);1483 const stack_offset = try self.allocMem(inst, tuple_size, tuple_align);
...@@ -2682,7 +2687,6 @@ fn binOp(...@@ -2682,7 +2687,6 @@ fn binOp(
2682 lhs_ty: Type,2687 lhs_ty: Type,
2683 rhs_ty: Type,2688 rhs_ty: Type,
2684) InnerError!MCValue {2689) InnerError!MCValue {
2685 const target = self.target.*;
2686 switch (tag) {2690 switch (tag) {
2687 .add,2691 .add,
2688 .sub,2692 .sub,
...@@ -2692,7 +2696,8 @@ fn binOp(...@@ -2692,7 +2696,8 @@ fn binOp(
2692 .Float => return self.fail("TODO ARM binary operations on floats", .{}),2696 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
2693 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),2697 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
2694 .Int => {2698 .Int => {
2695 assert(lhs_ty.eql(rhs_ty, target));2699 const mod = self.bin_file.options.module.?;
2700 assert(lhs_ty.eql(rhs_ty, mod));
2696 const int_info = lhs_ty.intInfo(self.target.*);2701 const int_info = lhs_ty.intInfo(self.target.*);
2697 if (int_info.bits <= 32) {2702 if (int_info.bits <= 32) {
2698 // Only say yes if the operation is2703 // Only say yes if the operation is
...@@ -2740,7 +2745,8 @@ fn binOp(...@@ -2740,7 +2745,8 @@ fn binOp(
2740 .Float => return self.fail("TODO ARM binary operations on floats", .{}),2745 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
2741 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),2746 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
2742 .Int => {2747 .Int => {
2743 assert(lhs_ty.eql(rhs_ty, target));2748 const mod = self.bin_file.options.module.?;
2749 assert(lhs_ty.eql(rhs_ty, mod));
2744 const int_info = lhs_ty.intInfo(self.target.*);2750 const int_info = lhs_ty.intInfo(self.target.*);
2745 if (int_info.bits <= 32) {2751 if (int_info.bits <= 32) {
2746 // TODO add optimisations for multiplication2752 // TODO add optimisations for multiplication
...@@ -2794,7 +2800,8 @@ fn binOp(...@@ -2794,7 +2800,8 @@ fn binOp(
2794 switch (lhs_ty.zigTypeTag()) {2800 switch (lhs_ty.zigTypeTag()) {
2795 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),2801 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
2796 .Int => {2802 .Int => {
2797 assert(lhs_ty.eql(rhs_ty, target));2803 const mod = self.bin_file.options.module.?;
2804 assert(lhs_ty.eql(rhs_ty, mod));
2798 const int_info = lhs_ty.intInfo(self.target.*);2805 const int_info = lhs_ty.intInfo(self.target.*);
2799 if (int_info.bits <= 32) {2806 if (int_info.bits <= 32) {
2800 const lhs_immediate_ok = lhs == .immediate and Instruction.Operand.fromU32(lhs.immediate) != null;2807 const lhs_immediate_ok = lhs == .immediate and Instruction.Operand.fromU32(lhs.immediate) != null;
...@@ -3100,8 +3107,9 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) error{OutOfMemory}!void {...@@ -3100,8 +3107,9 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) error{OutOfMemory}!void {
3100 const dbg_info = &dw.dbg_info;3107 const dbg_info = &dw.dbg_info;
3101 const index = dbg_info.items.len;3108 const index = dbg_info.items.len;
3102 try dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref43109 try dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4
3110 const mod = self.bin_file.options.module.?;
3103 const atom = switch (self.bin_file.tag) {3111 const atom = switch (self.bin_file.tag) {
3104 .elf => &self.mod_fn.owner_decl.link.elf.dbg_info_atom,3112 .elf => &mod.declPtr(self.mod_fn.owner_decl).link.elf.dbg_info_atom,
3105 .macho => unreachable,3113 .macho => unreachable,
3106 else => unreachable,3114 else => unreachable,
3107 };3115 };
...@@ -3318,11 +3326,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -3318,11 +3326,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
3318 const func = func_payload.data;3326 const func = func_payload.data;
3319 const ptr_bits = self.target.cpu.arch.ptrBitWidth();3327 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
3320 const ptr_bytes: u64 = @divExact(ptr_bits, 8);3328 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
3329 const mod = self.bin_file.options.module.?;
3330 const fn_owner_decl = mod.declPtr(func.owner_decl);
3321 const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: {3331 const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: {
3322 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];3332 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
3323 break :blk @intCast(u32, got.p_vaddr + func.owner_decl.link.elf.offset_table_index * ptr_bytes);3333 break :blk @intCast(u32, got.p_vaddr + fn_owner_decl.link.elf.offset_table_index * ptr_bytes);
3324 } else if (self.bin_file.cast(link.File.Coff)) |coff_file|3334 } else if (self.bin_file.cast(link.File.Coff)) |coff_file|
3325 coff_file.offset_table_virtual_address + func.owner_decl.link.coff.offset_table_index * ptr_bytes3335 coff_file.offset_table_virtual_address + fn_owner_decl.link.coff.offset_table_index * ptr_bytes
3326 else3336 else
3327 unreachable;3337 unreachable;
33283338
...@@ -4924,11 +4934,14 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {...@@ -4924,11 +4934,14 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
4924 }4934 }
4925}4935}
49264936
4927fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCValue {4937fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) InnerError!MCValue {
4928 const ptr_bits = self.target.cpu.arch.ptrBitWidth();4938 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
4929 const ptr_bytes: u64 = @divExact(ptr_bits, 8);4939 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
49304940
4931 decl.alive = true;4941 const mod = self.bin_file.options.module.?;
4942 const decl = mod.declPtr(decl_index);
4943 mod.markDeclAlive(decl);
4944
4932 if (self.bin_file.cast(link.File.Elf)) |elf_file| {4945 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
4933 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];4946 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
4934 const got_addr = got.p_vaddr + decl.link.elf.offset_table_index * ptr_bytes;4947 const got_addr = got.p_vaddr + decl.link.elf.offset_table_index * ptr_bytes;
...@@ -4939,7 +4952,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa...@@ -4939,7 +4952,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa
4939 const got_addr = coff_file.offset_table_virtual_address + decl.link.coff.offset_table_index * ptr_bytes;4952 const got_addr = coff_file.offset_table_virtual_address + decl.link.coff.offset_table_index * ptr_bytes;
4940 return MCValue{ .memory = got_addr };4953 return MCValue{ .memory = got_addr };
4941 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {4954 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
4942 try p9.seeDecl(decl);4955 try p9.seeDecl(decl_index);
4943 const got_addr = p9.bases.data + decl.link.plan9.got_index.? * ptr_bytes;4956 const got_addr = p9.bases.data + decl.link.plan9.got_index.? * ptr_bytes;
4944 return MCValue{ .memory = got_addr };4957 return MCValue{ .memory = got_addr };
4945 } else {4958 } else {
...@@ -4976,7 +4989,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -4976,7 +4989,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
4976 return self.lowerDeclRef(typed_value, payload.data);4989 return self.lowerDeclRef(typed_value, payload.data);
4977 }4990 }
4978 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {4991 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {
4979 return self.lowerDeclRef(typed_value, payload.data.decl);4992 return self.lowerDeclRef(typed_value, payload.data.decl_index);
4980 }4993 }
4981 const target = self.target.*;4994 const target = self.target.*;
49824995
src/arch/riscv64/CodeGen.zig+26-16
...@@ -229,8 +229,10 @@ pub fn generate(...@@ -229,8 +229,10 @@ pub fn generate(
229 @panic("Attempted to compile for architecture that was disabled by build configuration");229 @panic("Attempted to compile for architecture that was disabled by build configuration");
230 }230 }
231231
232 assert(module_fn.owner_decl.has_tv);232 const mod = bin_file.options.module.?;
233 const fn_type = module_fn.owner_decl.ty;233 const fn_owner_decl = mod.declPtr(module_fn.owner_decl);
234 assert(fn_owner_decl.has_tv);
235 const fn_type = fn_owner_decl.ty;
234236
235 var branch_stack = std.ArrayList(Branch).init(bin_file.allocator);237 var branch_stack = std.ArrayList(Branch).init(bin_file.allocator);
236 defer {238 defer {
...@@ -738,8 +740,9 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {...@@ -738,8 +740,9 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
738 const dbg_info = &dw.dbg_info;740 const dbg_info = &dw.dbg_info;
739 const index = dbg_info.items.len;741 const index = dbg_info.items.len;
740 try dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4742 try dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4
743 const mod = self.bin_file.options.module.?;
741 const atom = switch (self.bin_file.tag) {744 const atom = switch (self.bin_file.tag) {
742 .elf => &self.mod_fn.owner_decl.link.elf.dbg_info_atom,745 .elf => &mod.declPtr(self.mod_fn.owner_decl).link.elf.dbg_info_atom,
743 .macho => unreachable,746 .macho => unreachable,
744 else => unreachable,747 else => unreachable,
745 };748 };
...@@ -768,9 +771,9 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u...@@ -768,9 +771,9 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u
768/// Use a pointer instruction as the basis for allocating stack memory.771/// Use a pointer instruction as the basis for allocating stack memory.
769fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {772fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
770 const elem_ty = self.air.typeOfIndex(inst).elemType();773 const elem_ty = self.air.typeOfIndex(inst).elemType();
771 const target = self.target.*;
772 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {774 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
773 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});775 const mod = self.bin_file.options.module.?;
776 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
774 };777 };
775 // TODO swap this for inst.ty.ptrAlign778 // TODO swap this for inst.ty.ptrAlign
776 const abi_align = elem_ty.abiAlignment(self.target.*);779 const abi_align = elem_ty.abiAlignment(self.target.*);
...@@ -779,9 +782,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -779,9 +782,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
779782
780fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {783fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
781 const elem_ty = self.air.typeOfIndex(inst);784 const elem_ty = self.air.typeOfIndex(inst);
782 const target = self.target.*;
783 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {785 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
784 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});786 const mod = self.bin_file.options.module.?;
787 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
785 };788 };
786 const abi_align = elem_ty.abiAlignment(self.target.*);789 const abi_align = elem_ty.abiAlignment(self.target.*);
787 if (abi_align > self.stack_align)790 if (abi_align > self.stack_align)
...@@ -1037,7 +1040,8 @@ fn binOp(...@@ -1037,7 +1040,8 @@ fn binOp(
1037 .Float => return self.fail("TODO binary operations on floats", .{}),1040 .Float => return self.fail("TODO binary operations on floats", .{}),
1038 .Vector => return self.fail("TODO binary operations on vectors", .{}),1041 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1039 .Int => {1042 .Int => {
1040 assert(lhs_ty.eql(rhs_ty, self.target.*));1043 const mod = self.bin_file.options.module.?;
1044 assert(lhs_ty.eql(rhs_ty, mod));
1041 const int_info = lhs_ty.intInfo(self.target.*);1045 const int_info = lhs_ty.intInfo(self.target.*);
1042 if (int_info.bits <= 64) {1046 if (int_info.bits <= 64) {
1043 // TODO immediate operands1047 // TODO immediate operands
...@@ -1679,11 +1683,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -1679,11 +1683,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
16791683
1680 const ptr_bits = self.target.cpu.arch.ptrBitWidth();1684 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
1681 const ptr_bytes: u64 = @divExact(ptr_bits, 8);1685 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
1686 const mod = self.bin_file.options.module.?;
1687 const fn_owner_decl = mod.declPtr(func.owner_decl);
1682 const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: {1688 const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: {
1683 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];1689 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
1684 break :blk @intCast(u32, got.p_vaddr + func.owner_decl.link.elf.offset_table_index * ptr_bytes);1690 break :blk @intCast(u32, got.p_vaddr + fn_owner_decl.link.elf.offset_table_index * ptr_bytes);
1685 } else if (self.bin_file.cast(link.File.Coff)) |coff_file|1691 } else if (self.bin_file.cast(link.File.Coff)) |coff_file|
1686 coff_file.offset_table_virtual_address + func.owner_decl.link.coff.offset_table_index * ptr_bytes1692 coff_file.offset_table_virtual_address + fn_owner_decl.link.coff.offset_table_index * ptr_bytes
1687 else1693 else
1688 unreachable;1694 unreachable;
16891695
...@@ -1768,7 +1774,8 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -1768,7 +1774,8 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
1768 if (self.liveness.isUnused(inst))1774 if (self.liveness.isUnused(inst))
1769 return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });1775 return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });
1770 const ty = self.air.typeOf(bin_op.lhs);1776 const ty = self.air.typeOf(bin_op.lhs);
1771 assert(ty.eql(self.air.typeOf(bin_op.rhs), self.target.*));1777 const mod = self.bin_file.options.module.?;
1778 assert(ty.eql(self.air.typeOf(bin_op.rhs), mod));
1772 if (ty.zigTypeTag() == .ErrorSet)1779 if (ty.zigTypeTag() == .ErrorSet)
1773 return self.fail("TODO implement cmp for errors", .{});1780 return self.fail("TODO implement cmp for errors", .{});
17741781
...@@ -2501,10 +2508,12 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {...@@ -2501,10 +2508,12 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
2501 }2508 }
2502}2509}
25032510
2504fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCValue {2511fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) InnerError!MCValue {
2505 const ptr_bits = self.target.cpu.arch.ptrBitWidth();2512 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
2506 const ptr_bytes: u64 = @divExact(ptr_bits, 8);2513 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
2507 decl.alive = true;2514 const mod = self.bin_file.options.module.?;
2515 const decl = mod.declPtr(decl_index);
2516 mod.markDeclAlive(decl);
2508 if (self.bin_file.cast(link.File.Elf)) |elf_file| {2517 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
2509 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];2518 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
2510 const got_addr = got.p_vaddr + decl.link.elf.offset_table_index * ptr_bytes;2519 const got_addr = got.p_vaddr + decl.link.elf.offset_table_index * ptr_bytes;
...@@ -2517,7 +2526,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa...@@ -2517,7 +2526,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa
2517 const got_addr = coff_file.offset_table_virtual_address + decl.link.coff.offset_table_index * ptr_bytes;2526 const got_addr = coff_file.offset_table_virtual_address + decl.link.coff.offset_table_index * ptr_bytes;
2518 return MCValue{ .memory = got_addr };2527 return MCValue{ .memory = got_addr };
2519 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {2528 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
2520 try p9.seeDecl(decl);2529 try p9.seeDecl(decl_index);
2521 const got_addr = p9.bases.data + decl.link.plan9.got_index.? * ptr_bytes;2530 const got_addr = p9.bases.data + decl.link.plan9.got_index.? * ptr_bytes;
2522 return MCValue{ .memory = got_addr };2531 return MCValue{ .memory = got_addr };
2523 } else {2532 } else {
...@@ -2534,7 +2543,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -2534,7 +2543,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
2534 return self.lowerDeclRef(typed_value, payload.data);2543 return self.lowerDeclRef(typed_value, payload.data);
2535 }2544 }
2536 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {2545 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {
2537 return self.lowerDeclRef(typed_value, payload.data.decl);2546 return self.lowerDeclRef(typed_value, payload.data.decl_index);
2538 }2547 }
2539 const target = self.target.*;2548 const target = self.target.*;
2540 const ptr_bits = self.target.cpu.arch.ptrBitWidth();2549 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
...@@ -2544,7 +2553,8 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -2544,7 +2553,8 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
2544 var buf: Type.SlicePtrFieldTypeBuffer = undefined;2553 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
2545 const ptr_type = typed_value.ty.slicePtrFieldType(&buf);2554 const ptr_type = typed_value.ty.slicePtrFieldType(&buf);
2546 const ptr_mcv = try self.genTypedValue(.{ .ty = ptr_type, .val = typed_value.val });2555 const ptr_mcv = try self.genTypedValue(.{ .ty = ptr_type, .val = typed_value.val });
2547 const slice_len = typed_value.val.sliceLen(target);2556 const mod = self.bin_file.options.module.?;
2557 const slice_len = typed_value.val.sliceLen(mod);
2548 // Codegen can't handle some kinds of indirection. If the wrong union field is accessed here it may mean2558 // Codegen can't handle some kinds of indirection. If the wrong union field is accessed here it may mean
2549 // the Sema code needs to use anonymous Decls or alloca instructions to store data.2559 // the Sema code needs to use anonymous Decls or alloca instructions to store data.
2550 const ptr_imm = ptr_mcv.memory;2560 const ptr_imm = ptr_mcv.memory;
src/arch/sparcv9/CodeGen.zig+16-10
...@@ -243,8 +243,10 @@ pub fn generate(...@@ -243,8 +243,10 @@ pub fn generate(
243 @panic("Attempted to compile for architecture that was disabled by build configuration");243 @panic("Attempted to compile for architecture that was disabled by build configuration");
244 }244 }
245245
246 assert(module_fn.owner_decl.has_tv);246 const mod = bin_file.options.module.?;
247 const fn_type = module_fn.owner_decl.ty;247 const fn_owner_decl = mod.declPtr(module_fn.owner_decl);
248 assert(fn_owner_decl.has_tv);
249 const fn_type = fn_owner_decl.ty;
248250
249 var branch_stack = std.ArrayList(Branch).init(bin_file.allocator);251 var branch_stack = std.ArrayList(Branch).init(bin_file.allocator);
250 defer {252 defer {
...@@ -871,7 +873,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -871,7 +873,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
871 const ptr_bytes: u64 = @divExact(ptr_bits, 8);873 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
872 const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: {874 const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: {
873 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];875 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
874 break :blk @intCast(u32, got.p_vaddr + func.owner_decl.link.elf.offset_table_index * ptr_bytes);876 const mod = self.bin_file.options.module.?;
877 break :blk @intCast(u32, got.p_vaddr + mod.declPtr(func.owner_decl).link.elf.offset_table_index * ptr_bytes);
875 } else unreachable;878 } else unreachable;
876879
877 try self.genSetReg(Type.initTag(.usize), .o7, .{ .memory = got_addr });880 try self.genSetReg(Type.initTag(.usize), .o7, .{ .memory = got_addr });
...@@ -1026,9 +1029,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -1026,9 +1029,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
1026 return @as(u32, 0);1029 return @as(u32, 0);
1027 }1030 }
10281031
1029 const target = self.target.*;
1030 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {1032 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
1031 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});1033 const mod = self.bin_file.options.module.?;
1034 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
1032 };1035 };
1033 // TODO swap this for inst.ty.ptrAlign1036 // TODO swap this for inst.ty.ptrAlign
1034 const abi_align = elem_ty.abiAlignment(self.target.*);1037 const abi_align = elem_ty.abiAlignment(self.target.*);
...@@ -1037,9 +1040,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -1037,9 +1040,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
10371040
1038fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {1041fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
1039 const elem_ty = self.air.typeOfIndex(inst);1042 const elem_ty = self.air.typeOfIndex(inst);
1040 const target = self.target.*;
1041 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {1043 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
1042 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});1044 const mod = self.bin_file.options.module.?;
1045 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
1043 };1046 };
1044 const abi_align = elem_ty.abiAlignment(self.target.*);1047 const abi_align = elem_ty.abiAlignment(self.target.*);
1045 if (abi_align > self.stack_align)1048 if (abi_align > self.stack_align)
...@@ -1372,7 +1375,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -1372,7 +1375,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
1372 return self.lowerDeclRef(typed_value, payload.data);1375 return self.lowerDeclRef(typed_value, payload.data);
1373 }1376 }
1374 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {1377 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {
1375 return self.lowerDeclRef(typed_value, payload.data.decl);1378 return self.lowerDeclRef(typed_value, payload.data.decl_index);
1376 }1379 }
1377 const target = self.target.*;1380 const target = self.target.*;
13781381
...@@ -1422,7 +1425,7 @@ fn iterateBigTomb(self: *Self, inst: Air.Inst.Index, operand_count: usize) !BigT...@@ -1422,7 +1425,7 @@ fn iterateBigTomb(self: *Self, inst: Air.Inst.Index, operand_count: usize) !BigT
1422 };1425 };
1423}1426}
14241427
1425fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCValue {1428fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) InnerError!MCValue {
1426 const ptr_bits = self.target.cpu.arch.ptrBitWidth();1429 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
1427 const ptr_bytes: u64 = @divExact(ptr_bits, 8);1430 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
14281431
...@@ -1434,7 +1437,10 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa...@@ -1434,7 +1437,10 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa
1434 }1437 }
1435 }1438 }
14361439
1437 decl.alive = true;1440 const mod = self.bin_file.options.module.?;
1441 const decl = mod.declPtr(decl_index);
1442
1443 mod.markDeclAlive(decl);
1438 if (self.bin_file.cast(link.File.Elf)) |elf_file| {1444 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
1439 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];1445 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
1440 const got_addr = got.p_vaddr + decl.link.elf.offset_table_index * ptr_bytes;1446 const got_addr = got.p_vaddr + decl.link.elf.offset_table_index * ptr_bytes;
src/arch/wasm/CodeGen.zig+52-35
...@@ -538,6 +538,10 @@ const Self = @This();...@@ -538,6 +538,10 @@ const Self = @This();
538/// Reference to the function declaration the code538/// Reference to the function declaration the code
539/// section belongs to539/// section belongs to
540decl: *Decl,540decl: *Decl,
541decl_index: Decl.Index,
542/// Current block depth. Used to calculate the relative difference between a break
543/// and block
544block_depth: u32 = 0,
541air: Air,545air: Air,
542liveness: Liveness,546liveness: Liveness,
543gpa: mem.Allocator,547gpa: mem.Allocator,
...@@ -559,9 +563,6 @@ local_index: u32 = 0,...@@ -559,9 +563,6 @@ local_index: u32 = 0,
559arg_index: u32 = 0,563arg_index: u32 = 0,
560/// If codegen fails, an error messages will be allocated and saved in `err_msg`564/// If codegen fails, an error messages will be allocated and saved in `err_msg`
561err_msg: *Module.ErrorMsg,565err_msg: *Module.ErrorMsg,
562/// Current block depth. Used to calculate the relative difference between a break
563/// and block
564block_depth: u32 = 0,
565/// List of all locals' types generated throughout this declaration566/// List of all locals' types generated throughout this declaration
566/// used to emit locals count at start of 'code' section.567/// used to emit locals count at start of 'code' section.
567locals: std.ArrayListUnmanaged(u8),568locals: std.ArrayListUnmanaged(u8),
...@@ -644,7 +645,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!WValue {...@@ -644,7 +645,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!WValue {
644 // In the other cases, we will simply lower the constant to a value that fits645 // In the other cases, we will simply lower the constant to a value that fits
645 // into a single local (such as a pointer, integer, bool, etc).646 // into a single local (such as a pointer, integer, bool, etc).
646 const result = if (isByRef(ty, self.target)) blk: {647 const result = if (isByRef(ty, self.target)) blk: {
647 const sym_index = try self.bin_file.lowerUnnamedConst(self.decl, .{ .ty = ty, .val = val });648 const sym_index = try self.bin_file.lowerUnnamedConst(.{ .ty = ty, .val = val }, self.decl_index);
648 break :blk WValue{ .memory = sym_index };649 break :blk WValue{ .memory = sym_index };
649 } else try self.lowerConstant(val, ty);650 } else try self.lowerConstant(val, ty);
650651
...@@ -838,7 +839,8 @@ pub fn generate(...@@ -838,7 +839,8 @@ pub fn generate(
838 .liveness = liveness,839 .liveness = liveness,
839 .values = .{},840 .values = .{},
840 .code = code,841 .code = code,
841 .decl = func.owner_decl,842 .decl_index = func.owner_decl,
843 .decl = bin_file.options.module.?.declPtr(func.owner_decl),
842 .err_msg = undefined,844 .err_msg = undefined,
843 .locals = .{},845 .locals = .{},
844 .target = bin_file.options.target,846 .target = bin_file.options.target,
...@@ -1022,8 +1024,9 @@ fn allocStack(self: *Self, ty: Type) !WValue {...@@ -1022,8 +1024,9 @@ fn allocStack(self: *Self, ty: Type) !WValue {
1022 }1024 }
10231025
1024 const abi_size = std.math.cast(u32, ty.abiSize(self.target)) catch {1026 const abi_size = std.math.cast(u32, ty.abiSize(self.target)) catch {
1027 const module = self.bin_file.base.options.module.?;
1025 return self.fail("Type {} with ABI size of {d} exceeds stack frame size", .{1028 return self.fail("Type {} with ABI size of {d} exceeds stack frame size", .{
1026 ty.fmt(self.target), ty.abiSize(self.target),1029 ty.fmt(module), ty.abiSize(self.target),
1027 });1030 });
1028 };1031 };
1029 const abi_align = ty.abiAlignment(self.target);1032 const abi_align = ty.abiAlignment(self.target);
...@@ -1056,8 +1059,9 @@ fn allocStackPtr(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1056,8 +1059,9 @@ fn allocStackPtr(self: *Self, inst: Air.Inst.Index) !WValue {
10561059
1057 const abi_alignment = ptr_ty.ptrAlignment(self.target);1060 const abi_alignment = ptr_ty.ptrAlignment(self.target);
1058 const abi_size = std.math.cast(u32, pointee_ty.abiSize(self.target)) catch {1061 const abi_size = std.math.cast(u32, pointee_ty.abiSize(self.target)) catch {
1062 const module = self.bin_file.base.options.module.?;
1059 return self.fail("Type {} with ABI size of {d} exceeds stack frame size", .{1063 return self.fail("Type {} with ABI size of {d} exceeds stack frame size", .{
1060 pointee_ty.fmt(self.target), pointee_ty.abiSize(self.target),1064 pointee_ty.fmt(module), pointee_ty.abiSize(self.target),
1061 });1065 });
1062 };1066 };
1063 if (abi_alignment > self.stack_alignment) {1067 if (abi_alignment > self.stack_alignment) {
...@@ -1542,20 +1546,21 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -1542,20 +1546,21 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
1542 const ret_ty = fn_ty.fnReturnType();1546 const ret_ty = fn_ty.fnReturnType();
1543 const first_param_sret = isByRef(ret_ty, self.target);1547 const first_param_sret = isByRef(ret_ty, self.target);
15441548
1545 const target: ?*Decl = blk: {1549 const callee: ?*Decl = blk: {
1546 const func_val = self.air.value(pl_op.operand) orelse break :blk null;1550 const func_val = self.air.value(pl_op.operand) orelse break :blk null;
1551 const module = self.bin_file.base.options.module.?;
15471552
1548 if (func_val.castTag(.function)) |func| {1553 if (func_val.castTag(.function)) |func| {
1549 break :blk func.data.owner_decl;1554 break :blk module.declPtr(func.data.owner_decl);
1550 } else if (func_val.castTag(.extern_fn)) |extern_fn| {1555 } else if (func_val.castTag(.extern_fn)) |extern_fn| {
1551 const ext_decl = extern_fn.data.owner_decl;1556 const ext_decl = module.declPtr(extern_fn.data.owner_decl);
1552 var func_type = try genFunctype(self.gpa, ext_decl.ty, self.target);1557 var func_type = try genFunctype(self.gpa, ext_decl.ty, self.target);
1553 defer func_type.deinit(self.gpa);1558 defer func_type.deinit(self.gpa);
1554 ext_decl.fn_link.wasm.type_index = try self.bin_file.putOrGetFuncType(func_type);1559 ext_decl.fn_link.wasm.type_index = try self.bin_file.putOrGetFuncType(func_type);
1555 try self.bin_file.addOrUpdateImport(ext_decl);1560 try self.bin_file.addOrUpdateImport(ext_decl);
1556 break :blk ext_decl;1561 break :blk ext_decl;
1557 } else if (func_val.castTag(.decl_ref)) |decl_ref| {1562 } else if (func_val.castTag(.decl_ref)) |decl_ref| {
1558 break :blk decl_ref.data;1563 break :blk module.declPtr(decl_ref.data);
1559 }1564 }
1560 return self.fail("Expected a function, but instead found type '{s}'", .{func_val.tag()});1565 return self.fail("Expected a function, but instead found type '{s}'", .{func_val.tag()});
1561 };1566 };
...@@ -1580,7 +1585,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -1580,7 +1585,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
1580 }1585 }
1581 }1586 }
15821587
1583 if (target) |direct| {1588 if (callee) |direct| {
1584 try self.addLabel(.call, direct.link.wasm.sym_index);1589 try self.addLabel(.call, direct.link.wasm.sym_index);
1585 } else {1590 } else {
1586 // in this case we call a function pointer1591 // in this case we call a function pointer
...@@ -1837,16 +1842,16 @@ fn wrapBinOp(self: *Self, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError...@@ -1837,16 +1842,16 @@ fn wrapBinOp(self: *Self, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError
1837fn lowerParentPtr(self: *Self, ptr_val: Value, ptr_child_ty: Type) InnerError!WValue {1842fn lowerParentPtr(self: *Self, ptr_val: Value, ptr_child_ty: Type) InnerError!WValue {
1838 switch (ptr_val.tag()) {1843 switch (ptr_val.tag()) {
1839 .decl_ref_mut => {1844 .decl_ref_mut => {
1840 const decl = ptr_val.castTag(.decl_ref_mut).?.data.decl;1845 const decl_index = ptr_val.castTag(.decl_ref_mut).?.data.decl_index;
1841 return self.lowerParentPtrDecl(ptr_val, decl);1846 return self.lowerParentPtrDecl(ptr_val, decl_index);
1842 },1847 },
1843 .decl_ref => {1848 .decl_ref => {
1844 const decl = ptr_val.castTag(.decl_ref).?.data;1849 const decl_index = ptr_val.castTag(.decl_ref).?.data;
1845 return self.lowerParentPtrDecl(ptr_val, decl);1850 return self.lowerParentPtrDecl(ptr_val, decl_index);
1846 },1851 },
1847 .variable => {1852 .variable => {
1848 const decl = ptr_val.castTag(.variable).?.data.owner_decl;1853 const decl_index = ptr_val.castTag(.variable).?.data.owner_decl;
1849 return self.lowerParentPtrDecl(ptr_val, decl);1854 return self.lowerParentPtrDecl(ptr_val, decl_index);
1850 },1855 },
1851 .field_ptr => {1856 .field_ptr => {
1852 const field_ptr = ptr_val.castTag(.field_ptr).?.data;1857 const field_ptr = ptr_val.castTag(.field_ptr).?.data;
...@@ -1918,24 +1923,31 @@ fn lowerParentPtr(self: *Self, ptr_val: Value, ptr_child_ty: Type) InnerError!WV...@@ -1918,24 +1923,31 @@ fn lowerParentPtr(self: *Self, ptr_val: Value, ptr_child_ty: Type) InnerError!WV
1918 }1923 }
1919}1924}
19201925
1921fn lowerParentPtrDecl(self: *Self, ptr_val: Value, decl: *Module.Decl) InnerError!WValue {1926fn lowerParentPtrDecl(self: *Self, ptr_val: Value, decl_index: Module.Decl.Index) InnerError!WValue {
1922 decl.markAlive();1927 const module = self.bin_file.base.options.module.?;
1928 const decl = module.declPtr(decl_index);
1929 module.markDeclAlive(decl);
1923 var ptr_ty_payload: Type.Payload.ElemType = .{1930 var ptr_ty_payload: Type.Payload.ElemType = .{
1924 .base = .{ .tag = .single_mut_pointer },1931 .base = .{ .tag = .single_mut_pointer },
1925 .data = decl.ty,1932 .data = decl.ty,
1926 };1933 };
1927 const ptr_ty = Type.initPayload(&ptr_ty_payload.base);1934 const ptr_ty = Type.initPayload(&ptr_ty_payload.base);
1928 return self.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl);1935 return self.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index);
1929}1936}
19301937
1931fn lowerDeclRefValue(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!WValue {1938fn lowerDeclRefValue(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) InnerError!WValue {
1932 if (tv.ty.isSlice()) {1939 if (tv.ty.isSlice()) {
1933 return WValue{ .memory = try self.bin_file.lowerUnnamedConst(decl, tv) };1940 return WValue{ .memory = try self.bin_file.lowerUnnamedConst(tv, decl_index) };
1934 } else if (decl.ty.zigTypeTag() != .Fn and !decl.ty.hasRuntimeBitsIgnoreComptime()) {1941 }
1942
1943 const module = self.bin_file.base.options.module.?;
1944 const decl = module.declPtr(decl_index);
1945 if (decl.ty.zigTypeTag() != .Fn and !decl.ty.hasRuntimeBitsIgnoreComptime()) {
1935 return WValue{ .imm32 = 0xaaaaaaaa };1946 return WValue{ .imm32 = 0xaaaaaaaa };
1936 }1947 }
19371948
1938 decl.markAlive();1949 module.markDeclAlive(decl);
1950
1939 const target_sym_index = decl.link.wasm.sym_index;1951 const target_sym_index = decl.link.wasm.sym_index;
1940 if (decl.ty.zigTypeTag() == .Fn) {1952 if (decl.ty.zigTypeTag() == .Fn) {
1941 try self.bin_file.addTableFunction(target_sym_index);1953 try self.bin_file.addTableFunction(target_sym_index);
...@@ -1946,12 +1958,12 @@ fn lowerDeclRefValue(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError...@@ -1946,12 +1958,12 @@ fn lowerDeclRefValue(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError
1946fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {1958fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {
1947 if (val.isUndefDeep()) return self.emitUndefined(ty);1959 if (val.isUndefDeep()) return self.emitUndefined(ty);
1948 if (val.castTag(.decl_ref)) |decl_ref| {1960 if (val.castTag(.decl_ref)) |decl_ref| {
1949 const decl = decl_ref.data;1961 const decl_index = decl_ref.data;
1950 return self.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl);1962 return self.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl_index);
1951 }1963 }
1952 if (val.castTag(.decl_ref_mut)) |decl_ref| {1964 if (val.castTag(.decl_ref_mut)) |decl_ref_mut| {
1953 const decl = decl_ref.data.decl;1965 const decl_index = decl_ref_mut.data.decl_index;
1954 return self.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl);1966 return self.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl_index);
1955 }1967 }
19561968
1957 const target = self.target;1969 const target = self.target;
...@@ -2347,8 +2359,9 @@ fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -2347,8 +2359,9 @@ fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2347 const struct_ptr = try self.resolveInst(extra.data.struct_operand);2359 const struct_ptr = try self.resolveInst(extra.data.struct_operand);
2348 const struct_ty = self.air.typeOf(extra.data.struct_operand).childType();2360 const struct_ty = self.air.typeOf(extra.data.struct_operand).childType();
2349 const offset = std.math.cast(u32, struct_ty.structFieldOffset(extra.data.field_index, self.target)) catch {2361 const offset = std.math.cast(u32, struct_ty.structFieldOffset(extra.data.field_index, self.target)) catch {
2362 const module = self.bin_file.base.options.module.?;
2350 return self.fail("Field type '{}' too big to fit into stack frame", .{2363 return self.fail("Field type '{}' too big to fit into stack frame", .{
2351 struct_ty.structFieldType(extra.data.field_index).fmt(self.target),2364 struct_ty.structFieldType(extra.data.field_index).fmt(module),
2352 });2365 });
2353 };2366 };
2354 return self.structFieldPtr(struct_ptr, offset);2367 return self.structFieldPtr(struct_ptr, offset);
...@@ -2360,8 +2373,9 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u32) InnerEr...@@ -2360,8 +2373,9 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u32) InnerEr
2360 const struct_ty = self.air.typeOf(ty_op.operand).childType();2373 const struct_ty = self.air.typeOf(ty_op.operand).childType();
2361 const field_ty = struct_ty.structFieldType(index);2374 const field_ty = struct_ty.structFieldType(index);
2362 const offset = std.math.cast(u32, struct_ty.structFieldOffset(index, self.target)) catch {2375 const offset = std.math.cast(u32, struct_ty.structFieldOffset(index, self.target)) catch {
2376 const module = self.bin_file.base.options.module.?;
2363 return self.fail("Field type '{}' too big to fit into stack frame", .{2377 return self.fail("Field type '{}' too big to fit into stack frame", .{
2364 field_ty.fmt(self.target),2378 field_ty.fmt(module),
2365 });2379 });
2366 };2380 };
2367 return self.structFieldPtr(struct_ptr, offset);2381 return self.structFieldPtr(struct_ptr, offset);
...@@ -2387,7 +2401,8 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -2387,7 +2401,8 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2387 const field_ty = struct_ty.structFieldType(field_index);2401 const field_ty = struct_ty.structFieldType(field_index);
2388 if (!field_ty.hasRuntimeBitsIgnoreComptime()) return WValue{ .none = {} };2402 if (!field_ty.hasRuntimeBitsIgnoreComptime()) return WValue{ .none = {} };
2389 const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, self.target)) catch {2403 const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, self.target)) catch {
2390 return self.fail("Field type '{}' too big to fit into stack frame", .{field_ty.fmt(self.target)});2404 const module = self.bin_file.base.options.module.?;
2405 return self.fail("Field type '{}' too big to fit into stack frame", .{field_ty.fmt(module)});
2391 };2406 };
23922407
2393 if (isByRef(field_ty, self.target)) {2408 if (isByRef(field_ty, self.target)) {
...@@ -2782,7 +2797,8 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) InnerError!WValue...@@ -2782,7 +2797,8 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) InnerError!WValue
2782 }2797 }
27832798
2784 const offset = std.math.cast(u32, opt_ty.abiSize(self.target) - payload_ty.abiSize(self.target)) catch {2799 const offset = std.math.cast(u32, opt_ty.abiSize(self.target) - payload_ty.abiSize(self.target)) catch {
2785 return self.fail("Optional type {} too big to fit into stack frame", .{opt_ty.fmt(self.target)});2800 const module = self.bin_file.base.options.module.?;
2801 return self.fail("Optional type {} too big to fit into stack frame", .{opt_ty.fmt(module)});
2786 };2802 };
27872803
2788 try self.emitWValue(operand);2804 try self.emitWValue(operand);
...@@ -2811,7 +2827,8 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -2811,7 +2827,8 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2811 return operand;2827 return operand;
2812 }2828 }
2813 const offset = std.math.cast(u32, op_ty.abiSize(self.target) - payload_ty.abiSize(self.target)) catch {2829 const offset = std.math.cast(u32, op_ty.abiSize(self.target) - payload_ty.abiSize(self.target)) catch {
2814 return self.fail("Optional type {} too big to fit into stack frame", .{op_ty.fmt(self.target)});2830 const module = self.bin_file.base.options.module.?;
2831 return self.fail("Optional type {} too big to fit into stack frame", .{op_ty.fmt(module)});
2815 };2832 };
28162833
2817 // Create optional type, set the non-null bit, and store the operand inside the optional type2834 // Create optional type, set the non-null bit, and store the operand inside the optional type
src/arch/x86_64/CodeGen.zig+32-21
...@@ -309,8 +309,10 @@ pub fn generate(...@@ -309,8 +309,10 @@ pub fn generate(
309 @panic("Attempted to compile for architecture that was disabled by build configuration");309 @panic("Attempted to compile for architecture that was disabled by build configuration");
310 }310 }
311311
312 assert(module_fn.owner_decl.has_tv);312 const mod = bin_file.options.module.?;
313 const fn_type = module_fn.owner_decl.ty;313 const fn_owner_decl = mod.declPtr(module_fn.owner_decl);
314 assert(fn_owner_decl.has_tv);
315 const fn_type = fn_owner_decl.ty;
314316
315 var branch_stack = std.ArrayList(Branch).init(bin_file.allocator);317 var branch_stack = std.ArrayList(Branch).init(bin_file.allocator);
316 defer {318 defer {
...@@ -396,14 +398,14 @@ pub fn generate(...@@ -396,14 +398,14 @@ pub fn generate(
396398
397 if (builtin.mode == .Debug and bin_file.options.module.?.comp.verbose_mir) {399 if (builtin.mode == .Debug and bin_file.options.module.?.comp.verbose_mir) {
398 const w = std.io.getStdErr().writer();400 const w = std.io.getStdErr().writer();
399 w.print("# Begin Function MIR: {s}:\n", .{module_fn.owner_decl.name}) catch {};401 w.print("# Begin Function MIR: {s}:\n", .{fn_owner_decl.name}) catch {};
400 const PrintMir = @import("PrintMir.zig");402 const PrintMir = @import("PrintMir.zig");
401 const print = PrintMir{403 const print = PrintMir{
402 .mir = mir,404 .mir = mir,
403 .bin_file = bin_file,405 .bin_file = bin_file,
404 };406 };
405 print.printMir(w, function.mir_to_air_map, air) catch {}; // we don't care if the debug printing fails407 print.printMir(w, function.mir_to_air_map, air) catch {}; // we don't care if the debug printing fails
406 w.print("# End Function MIR: {s}\n\n", .{module_fn.owner_decl.name}) catch {};408 w.print("# End Function MIR: {s}\n\n", .{fn_owner_decl.name}) catch {};
407 }409 }
408410
409 if (function.err_msg) |em| {411 if (function.err_msg) |em| {
...@@ -915,9 +917,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -915,9 +917,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
915 return self.allocMem(inst, @sizeOf(usize), @alignOf(usize));917 return self.allocMem(inst, @sizeOf(usize), @alignOf(usize));
916 }918 }
917919
918 const target = self.target.*;
919 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {920 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
920 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});921 const mod = self.bin_file.options.module.?;
922 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
921 };923 };
922 // TODO swap this for inst.ty.ptrAlign924 // TODO swap this for inst.ty.ptrAlign
923 const abi_align = ptr_ty.ptrAlignment(self.target.*);925 const abi_align = ptr_ty.ptrAlignment(self.target.*);
...@@ -926,9 +928,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -926,9 +928,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
926928
927fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {929fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
928 const elem_ty = self.air.typeOfIndex(inst);930 const elem_ty = self.air.typeOfIndex(inst);
929 const target = self.target.*;
930 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {931 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
931 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});932 const mod = self.bin_file.options.module.?;
933 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
932 };934 };
933 const abi_align = elem_ty.abiAlignment(self.target.*);935 const abi_align = elem_ty.abiAlignment(self.target.*);
934 if (abi_align > self.stack_align)936 if (abi_align > self.stack_align)
...@@ -2650,6 +2652,8 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue...@@ -2650,6 +2652,8 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue
2650 .direct_load => 0b01,2652 .direct_load => 0b01,
2651 else => unreachable,2653 else => unreachable,
2652 };2654 };
2655 const mod = self.bin_file.options.module.?;
2656 const fn_owner_decl = mod.declPtr(self.mod_fn.owner_decl);
2653 _ = try self.addInst(.{2657 _ = try self.addInst(.{
2654 .tag = .lea_pie,2658 .tag = .lea_pie,
2655 .ops = (Mir.Ops{2659 .ops = (Mir.Ops{
...@@ -2658,7 +2662,7 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue...@@ -2658,7 +2662,7 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue
2658 }).encode(),2662 }).encode(),
2659 .data = .{2663 .data = .{
2660 .load_reloc = .{2664 .load_reloc = .{
2661 .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index,2665 .atom_index = fn_owner_decl.link.macho.local_sym_index,
2662 .sym_index = sym_index,2666 .sym_index = sym_index,
2663 },2667 },
2664 },2668 },
...@@ -3583,17 +3587,19 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -3583,17 +3587,19 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
35833587
3584 // Due to incremental compilation, how function calls are generated depends3588 // Due to incremental compilation, how function calls are generated depends
3585 // on linking.3589 // on linking.
3590 const mod = self.bin_file.options.module.?;
3586 if (self.bin_file.tag == link.File.Elf.base_tag or self.bin_file.tag == link.File.Coff.base_tag) {3591 if (self.bin_file.tag == link.File.Elf.base_tag or self.bin_file.tag == link.File.Coff.base_tag) {
3587 if (self.air.value(callee)) |func_value| {3592 if (self.air.value(callee)) |func_value| {
3588 if (func_value.castTag(.function)) |func_payload| {3593 if (func_value.castTag(.function)) |func_payload| {
3589 const func = func_payload.data;3594 const func = func_payload.data;
3590 const ptr_bits = self.target.cpu.arch.ptrBitWidth();3595 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
3591 const ptr_bytes: u64 = @divExact(ptr_bits, 8);3596 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
3597 const fn_owner_decl = mod.declPtr(func.owner_decl);
3592 const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: {3598 const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: {
3593 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];3599 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
3594 break :blk @intCast(u32, got.p_vaddr + func.owner_decl.link.elf.offset_table_index * ptr_bytes);3600 break :blk @intCast(u32, got.p_vaddr + fn_owner_decl.link.elf.offset_table_index * ptr_bytes);
3595 } else if (self.bin_file.cast(link.File.Coff)) |coff_file|3601 } else if (self.bin_file.cast(link.File.Coff)) |coff_file|
3596 @intCast(u32, coff_file.offset_table_virtual_address + func.owner_decl.link.coff.offset_table_index * ptr_bytes)3602 @intCast(u32, coff_file.offset_table_virtual_address + fn_owner_decl.link.coff.offset_table_index * ptr_bytes)
3597 else3603 else
3598 unreachable;3604 unreachable;
3599 _ = try self.addInst(.{3605 _ = try self.addInst(.{
...@@ -3625,8 +3631,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -3625,8 +3631,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
3625 if (self.air.value(callee)) |func_value| {3631 if (self.air.value(callee)) |func_value| {
3626 if (func_value.castTag(.function)) |func_payload| {3632 if (func_value.castTag(.function)) |func_payload| {
3627 const func = func_payload.data;3633 const func = func_payload.data;
3634 const fn_owner_decl = mod.declPtr(func.owner_decl);
3628 try self.genSetReg(Type.initTag(.usize), .rax, .{3635 try self.genSetReg(Type.initTag(.usize), .rax, .{
3629 .got_load = func.owner_decl.link.macho.local_sym_index,3636 .got_load = fn_owner_decl.link.macho.local_sym_index,
3630 });3637 });
3631 // callq *%rax3638 // callq *%rax
3632 _ = try self.addInst(.{3639 _ = try self.addInst(.{
...@@ -3639,7 +3646,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -3639,7 +3646,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
3639 });3646 });
3640 } else if (func_value.castTag(.extern_fn)) |func_payload| {3647 } else if (func_value.castTag(.extern_fn)) |func_payload| {
3641 const extern_fn = func_payload.data;3648 const extern_fn = func_payload.data;
3642 const decl_name = extern_fn.owner_decl.name;3649 const decl_name = mod.declPtr(extern_fn.owner_decl).name;
3643 if (extern_fn.lib_name) |lib_name| {3650 if (extern_fn.lib_name) |lib_name| {
3644 log.debug("TODO enforce that '{s}' is expected in '{s}' library", .{3651 log.debug("TODO enforce that '{s}' is expected in '{s}' library", .{
3645 decl_name,3652 decl_name,
...@@ -3652,7 +3659,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -3652,7 +3659,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
3652 .ops = undefined,3659 .ops = undefined,
3653 .data = .{3660 .data = .{
3654 .extern_fn = .{3661 .extern_fn = .{
3655 .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index,3662 .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.local_sym_index,
3656 .sym_name = n_strx,3663 .sym_name = n_strx,
3657 },3664 },
3658 },3665 },
...@@ -3680,7 +3687,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -3680,7 +3687,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
3680 const ptr_bits = self.target.cpu.arch.ptrBitWidth();3687 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
3681 const ptr_bytes: u64 = @divExact(ptr_bits, 8);3688 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
3682 const got_addr = p9.bases.data;3689 const got_addr = p9.bases.data;
3683 const got_index = func_payload.data.owner_decl.link.plan9.got_index.?;3690 const got_index = mod.declPtr(func_payload.data.owner_decl).link.plan9.got_index.?;
3684 const fn_got_addr = got_addr + got_index * ptr_bytes;3691 const fn_got_addr = got_addr + got_index * ptr_bytes;
3685 _ = try self.addInst(.{3692 _ = try self.addInst(.{
3686 .tag = .call,3693 .tag = .call,
...@@ -4012,9 +4019,11 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {...@@ -4012,9 +4019,11 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
4012 const dbg_info = &dw.dbg_info;4019 const dbg_info = &dw.dbg_info;
4013 const index = dbg_info.items.len;4020 const index = dbg_info.items.len;
4014 try dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref44021 try dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4
4022 const mod = self.bin_file.options.module.?;
4023 const fn_owner_decl = mod.declPtr(self.mod_fn.owner_decl);
4015 const atom = switch (self.bin_file.tag) {4024 const atom = switch (self.bin_file.tag) {
4016 .elf => &self.mod_fn.owner_decl.link.elf.dbg_info_atom,4025 .elf => &fn_owner_decl.link.elf.dbg_info_atom,
4017 .macho => &self.mod_fn.owner_decl.link.macho.dbg_info_atom,4026 .macho => &fn_owner_decl.link.macho.dbg_info_atom,
4018 else => unreachable,4027 else => unreachable,
4019 };4028 };
4020 try dw.addTypeReloc(atom, ty, @intCast(u32, index), null);4029 try dw.addTypeReloc(atom, ty, @intCast(u32, index), null);
...@@ -6124,7 +6133,7 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV...@@ -6124,7 +6133,7 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV
6124 return mcv;6133 return mcv;
6125}6134}
61266135
6127fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCValue {6136fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) InnerError!MCValue {
6128 log.debug("lowerDeclRef: ty = {}, val = {}", .{ tv.ty.fmtDebug(), tv.val.fmtDebug() });6137 log.debug("lowerDeclRef: ty = {}, val = {}", .{ tv.ty.fmtDebug(), tv.val.fmtDebug() });
6129 const ptr_bits = self.target.cpu.arch.ptrBitWidth();6138 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
6130 const ptr_bytes: u64 = @divExact(ptr_bits, 8);6139 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
...@@ -6137,7 +6146,9 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa...@@ -6137,7 +6146,9 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa
6137 }6146 }
6138 }6147 }
61396148
6140 decl.markAlive();6149 const module = self.bin_file.options.module.?;
6150 const decl = module.declPtr(decl_index);
6151 module.markDeclAlive(decl);
61416152
6142 if (self.bin_file.cast(link.File.Elf)) |elf_file| {6153 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
6143 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];6154 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
...@@ -6152,7 +6163,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa...@@ -6152,7 +6163,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa
6152 const got_addr = coff_file.offset_table_virtual_address + decl.link.coff.offset_table_index * ptr_bytes;6163 const got_addr = coff_file.offset_table_virtual_address + decl.link.coff.offset_table_index * ptr_bytes;
6153 return MCValue{ .memory = got_addr };6164 return MCValue{ .memory = got_addr };
6154 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {6165 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
6155 try p9.seeDecl(decl);6166 try p9.seeDecl(decl_index);
6156 const got_addr = p9.bases.data + decl.link.plan9.got_index.? * ptr_bytes;6167 const got_addr = p9.bases.data + decl.link.plan9.got_index.? * ptr_bytes;
6157 return MCValue{ .memory = got_addr };6168 return MCValue{ .memory = got_addr };
6158 } else {6169 } else {
...@@ -6189,7 +6200,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -6189,7 +6200,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
6189 return self.lowerDeclRef(typed_value, payload.data);6200 return self.lowerDeclRef(typed_value, payload.data);
6190 }6201 }
6191 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {6202 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {
6192 return self.lowerDeclRef(typed_value, payload.data.decl);6203 return self.lowerDeclRef(typed_value, payload.data.decl_index);
6193 }6204 }
61946205
6195 const target = self.target.*;6206 const target = self.target.*;
src/codegen.zig+15-9
...@@ -347,7 +347,9 @@ pub fn generateSymbol(...@@ -347,7 +347,9 @@ pub fn generateSymbol(
347347
348 switch (container_ptr.tag()) {348 switch (container_ptr.tag()) {
349 .decl_ref => {349 .decl_ref => {
350 const decl = container_ptr.castTag(.decl_ref).?.data;350 const decl_index = container_ptr.castTag(.decl_ref).?.data;
351 const mod = bin_file.options.module.?;
352 const decl = mod.declPtr(decl_index);
351 const addend = blk: {353 const addend = blk: {
352 switch (decl.ty.tag()) {354 switch (decl.ty.tag()) {
353 .@"struct" => {355 .@"struct" => {
...@@ -364,7 +366,7 @@ pub fn generateSymbol(...@@ -364,7 +366,7 @@ pub fn generateSymbol(
364 },366 },
365 }367 }
366 };368 };
367 return lowerDeclRef(bin_file, src_loc, typed_value, decl, code, debug_output, .{369 return lowerDeclRef(bin_file, src_loc, typed_value, decl_index, code, debug_output, .{
368 .parent_atom_index = reloc_info.parent_atom_index,370 .parent_atom_index = reloc_info.parent_atom_index,
369 .addend = (reloc_info.addend orelse 0) + addend,371 .addend = (reloc_info.addend orelse 0) + addend,
370 });372 });
...@@ -400,8 +402,8 @@ pub fn generateSymbol(...@@ -400,8 +402,8 @@ pub fn generateSymbol(
400402
401 switch (array_ptr.tag()) {403 switch (array_ptr.tag()) {
402 .decl_ref => {404 .decl_ref => {
403 const decl = array_ptr.castTag(.decl_ref).?.data;405 const decl_index = array_ptr.castTag(.decl_ref).?.data;
404 return lowerDeclRef(bin_file, src_loc, typed_value, decl, code, debug_output, .{406 return lowerDeclRef(bin_file, src_loc, typed_value, decl_index, code, debug_output, .{
405 .parent_atom_index = reloc_info.parent_atom_index,407 .parent_atom_index = reloc_info.parent_atom_index,
406 .addend = (reloc_info.addend orelse 0) + addend,408 .addend = (reloc_info.addend orelse 0) + addend,
407 });409 });
...@@ -589,7 +591,8 @@ pub fn generateSymbol(...@@ -589,7 +591,8 @@ pub fn generateSymbol(
589 }591 }
590592
591 const union_ty = typed_value.ty.cast(Type.Payload.Union).?.data;593 const union_ty = typed_value.ty.cast(Type.Payload.Union).?.data;
592 const field_index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag, target).?;594 const mod = bin_file.options.module.?;
595 const field_index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag, mod).?;
593 assert(union_ty.haveFieldTypes());596 assert(union_ty.haveFieldTypes());
594 const field_ty = union_ty.fields.values()[field_index].ty;597 const field_ty = union_ty.fields.values()[field_index].ty;
595 if (!field_ty.hasRuntimeBits()) {598 if (!field_ty.hasRuntimeBits()) {
...@@ -772,12 +775,13 @@ fn lowerDeclRef(...@@ -772,12 +775,13 @@ fn lowerDeclRef(
772 bin_file: *link.File,775 bin_file: *link.File,
773 src_loc: Module.SrcLoc,776 src_loc: Module.SrcLoc,
774 typed_value: TypedValue,777 typed_value: TypedValue,
775 decl: *Module.Decl,778 decl_index: Module.Decl.Index,
776 code: *std.ArrayList(u8),779 code: *std.ArrayList(u8),
777 debug_output: DebugInfoOutput,780 debug_output: DebugInfoOutput,
778 reloc_info: RelocInfo,781 reloc_info: RelocInfo,
779) GenerateSymbolError!Result {782) GenerateSymbolError!Result {
780 const target = bin_file.options.target;783 const target = bin_file.options.target;
784 const module = bin_file.options.module.?;
781 if (typed_value.ty.isSlice()) {785 if (typed_value.ty.isSlice()) {
782 // generate ptr786 // generate ptr
783 var buf: Type.SlicePtrFieldTypeBuffer = undefined;787 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
...@@ -796,7 +800,7 @@ fn lowerDeclRef(...@@ -796,7 +800,7 @@ fn lowerDeclRef(
796 // generate length800 // generate length
797 var slice_len: Value.Payload.U64 = .{801 var slice_len: Value.Payload.U64 = .{
798 .base = .{ .tag = .int_u64 },802 .base = .{ .tag = .int_u64 },
799 .data = typed_value.val.sliceLen(target),803 .data = typed_value.val.sliceLen(module),
800 };804 };
801 switch (try generateSymbol(bin_file, src_loc, .{805 switch (try generateSymbol(bin_file, src_loc, .{
802 .ty = Type.usize,806 .ty = Type.usize,
...@@ -813,14 +817,16 @@ fn lowerDeclRef(...@@ -813,14 +817,16 @@ fn lowerDeclRef(
813 }817 }
814818
815 const ptr_width = target.cpu.arch.ptrBitWidth();819 const ptr_width = target.cpu.arch.ptrBitWidth();
820 const decl = module.declPtr(decl_index);
816 const is_fn_body = decl.ty.zigTypeTag() == .Fn;821 const is_fn_body = decl.ty.zigTypeTag() == .Fn;
817 if (!is_fn_body and !decl.ty.hasRuntimeBits()) {822 if (!is_fn_body and !decl.ty.hasRuntimeBits()) {
818 try code.writer().writeByteNTimes(0xaa, @divExact(ptr_width, 8));823 try code.writer().writeByteNTimes(0xaa, @divExact(ptr_width, 8));
819 return Result{ .appended = {} };824 return Result{ .appended = {} };
820 }825 }
821826
822 decl.markAlive();827 module.markDeclAlive(decl);
823 const vaddr = try bin_file.getDeclVAddr(decl, .{828
829 const vaddr = try bin_file.getDeclVAddr(decl_index, .{
824 .parent_atom_index = reloc_info.parent_atom_index,830 .parent_atom_index = reloc_info.parent_atom_index,
825 .offset = code.items.len,831 .offset = code.items.len,
826 .addend = reloc_info.addend orelse 0,832 .addend = reloc_info.addend orelse 0,
src/codegen/c.zig+43-44
...@@ -32,8 +32,8 @@ pub const CValue = union(enum) {...@@ -32,8 +32,8 @@ pub const CValue = union(enum) {
32 /// Index into the parameters32 /// Index into the parameters
33 arg: usize,33 arg: usize,
34 /// By-value34 /// By-value
35 decl: *Decl,35 decl: Decl.Index,
36 decl_ref: *Decl,36 decl_ref: Decl.Index,
37 /// An undefined (void *) pointer (cannot be dereferenced)37 /// An undefined (void *) pointer (cannot be dereferenced)
38 undefined_ptr: void,38 undefined_ptr: void,
39 /// Render the slice as an identifier (using fmtIdent)39 /// Render the slice as an identifier (using fmtIdent)
...@@ -58,7 +58,7 @@ pub const TypedefMap = std.ArrayHashMap(...@@ -58,7 +58,7 @@ pub const TypedefMap = std.ArrayHashMap(
5858
59const FormatTypeAsCIdentContext = struct {59const FormatTypeAsCIdentContext = struct {
60 ty: Type,60 ty: Type,
61 target: std.Target,61 mod: *Module,
62};62};
6363
64/// TODO make this not cut off at 128 bytes64/// TODO make this not cut off at 128 bytes
...@@ -71,14 +71,14 @@ fn formatTypeAsCIdentifier(...@@ -71,14 +71,14 @@ fn formatTypeAsCIdentifier(
71 _ = fmt;71 _ = fmt;
72 _ = options;72 _ = options;
73 var buffer = [1]u8{0} ** 128;73 var buffer = [1]u8{0} ** 128;
74 var buf = std.fmt.bufPrint(&buffer, "{}", .{data.ty.fmt(data.target)}) catch &buffer;74 var buf = std.fmt.bufPrint(&buffer, "{}", .{data.ty.fmt(data.mod)}) catch &buffer;
75 return formatIdent(buf, "", .{}, writer);75 return formatIdent(buf, "", .{}, writer);
76}76}
7777
78pub fn typeToCIdentifier(ty: Type, target: std.Target) std.fmt.Formatter(formatTypeAsCIdentifier) {78pub fn typeToCIdentifier(ty: Type, mod: *Module) std.fmt.Formatter(formatTypeAsCIdentifier) {
79 return .{ .data = .{79 return .{ .data = .{
80 .ty = ty,80 .ty = ty,
81 .target = target,81 .mod = mod,
82 } };82 } };
83}83}
8484
...@@ -349,6 +349,7 @@ pub const DeclGen = struct {...@@ -349,6 +349,7 @@ pub const DeclGen = struct {
349 gpa: std.mem.Allocator,349 gpa: std.mem.Allocator,
350 module: *Module,350 module: *Module,
351 decl: *Decl,351 decl: *Decl,
352 decl_index: Decl.Index,
352 fwd_decl: std.ArrayList(u8),353 fwd_decl: std.ArrayList(u8),
353 error_msg: ?*Module.ErrorMsg,354 error_msg: ?*Module.ErrorMsg,
354 /// The key of this map is Type which has references to typedefs_arena.355 /// The key of this map is Type which has references to typedefs_arena.
...@@ -376,10 +377,8 @@ pub const DeclGen = struct {...@@ -376,10 +377,8 @@ pub const DeclGen = struct {
376 writer: anytype,377 writer: anytype,
377 ty: Type,378 ty: Type,
378 val: Value,379 val: Value,
379 decl: *Decl,380 decl_index: Decl.Index,
380 ) error{ OutOfMemory, AnalysisFail }!void {381 ) error{ OutOfMemory, AnalysisFail }!void {
381 const target = dg.module.getTarget();
382
383 if (ty.isSlice()) {382 if (ty.isSlice()) {
384 try writer.writeByte('(');383 try writer.writeByte('(');
385 try dg.renderTypecast(writer, ty);384 try dg.renderTypecast(writer, ty);
...@@ -387,11 +386,12 @@ pub const DeclGen = struct {...@@ -387,11 +386,12 @@ pub const DeclGen = struct {
387 var buf: Type.SlicePtrFieldTypeBuffer = undefined;386 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
388 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr());387 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr());
389 try writer.writeAll(", ");388 try writer.writeAll(", ");
390 try writer.print("{d}", .{val.sliceLen(target)});389 try writer.print("{d}", .{val.sliceLen(dg.module)});
391 try writer.writeAll("}");390 try writer.writeAll("}");
392 return;391 return;
393 }392 }
394393
394 const decl = dg.module.declPtr(decl_index);
395 assert(decl.has_tv);395 assert(decl.has_tv);
396 // We shouldn't cast C function pointers as this is UB (when you call396 // We shouldn't cast C function pointers as this is UB (when you call
397 // them). The analysis until now should ensure that the C function397 // them). The analysis until now should ensure that the C function
...@@ -399,21 +399,21 @@ pub const DeclGen = struct {...@@ -399,21 +399,21 @@ pub const DeclGen = struct {
399 // somewhere and we should let the C compiler tell us about it.399 // somewhere and we should let the C compiler tell us about it.
400 if (ty.castPtrToFn() == null) {400 if (ty.castPtrToFn() == null) {
401 // Determine if we must pointer cast.401 // Determine if we must pointer cast.
402 if (ty.eql(decl.ty, target)) {402 if (ty.eql(decl.ty, dg.module)) {
403 try writer.writeByte('&');403 try writer.writeByte('&');
404 try dg.renderDeclName(writer, decl);404 try dg.renderDeclName(writer, decl_index);
405 return;405 return;
406 }406 }
407407
408 try writer.writeAll("((");408 try writer.writeAll("((");
409 try dg.renderTypecast(writer, ty);409 try dg.renderTypecast(writer, ty);
410 try writer.writeAll(")&");410 try writer.writeAll(")&");
411 try dg.renderDeclName(writer, decl);411 try dg.renderDeclName(writer, decl_index);
412 try writer.writeByte(')');412 try writer.writeByte(')');
413 return;413 return;
414 }414 }
415415
416 try dg.renderDeclName(writer, decl);416 try dg.renderDeclName(writer, decl_index);
417 }417 }
418418
419 fn renderInt128(419 fn renderInt128(
...@@ -471,13 +471,13 @@ pub const DeclGen = struct {...@@ -471,13 +471,13 @@ pub const DeclGen = struct {
471 try writer.writeByte(')');471 try writer.writeByte(')');
472 switch (ptr_val.tag()) {472 switch (ptr_val.tag()) {
473 .decl_ref_mut, .decl_ref, .variable => {473 .decl_ref_mut, .decl_ref, .variable => {
474 const decl = switch (ptr_val.tag()) {474 const decl_index = switch (ptr_val.tag()) {
475 .decl_ref => ptr_val.castTag(.decl_ref).?.data,475 .decl_ref => ptr_val.castTag(.decl_ref).?.data,
476 .decl_ref_mut => ptr_val.castTag(.decl_ref_mut).?.data.decl,476 .decl_ref_mut => ptr_val.castTag(.decl_ref_mut).?.data.decl_index,
477 .variable => ptr_val.castTag(.variable).?.data.owner_decl,477 .variable => ptr_val.castTag(.variable).?.data.owner_decl,
478 else => unreachable,478 else => unreachable,
479 };479 };
480 try dg.renderDeclValue(writer, ptr_ty, ptr_val, decl);480 try dg.renderDeclValue(writer, ptr_ty, ptr_val, decl_index);
481 },481 },
482 .field_ptr => {482 .field_ptr => {
483 const field_ptr = ptr_val.castTag(.field_ptr).?.data;483 const field_ptr = ptr_val.castTag(.field_ptr).?.data;
...@@ -685,7 +685,7 @@ pub const DeclGen = struct {...@@ -685,7 +685,7 @@ pub const DeclGen = struct {
685 var index: usize = 0;685 var index: usize = 0;
686 while (index < ai.len) : (index += 1) {686 while (index < ai.len) : (index += 1) {
687 if (index != 0) try writer.writeAll(",");687 if (index != 0) try writer.writeAll(",");
688 const elem_val = try val.elemValue(arena_allocator, index);688 const elem_val = try val.elemValue(dg.module, arena_allocator, index);
689 try dg.renderValue(writer, ai.elem_type, elem_val);689 try dg.renderValue(writer, ai.elem_type, elem_val);
690 }690 }
691 if (ai.sentinel) |s| {691 if (ai.sentinel) |s| {
...@@ -837,7 +837,7 @@ pub const DeclGen = struct {...@@ -837,7 +837,7 @@ pub const DeclGen = struct {
837 try writer.writeAll(".payload = {");837 try writer.writeAll(".payload = {");
838 }838 }
839839
840 const index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag, target).?;840 const index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag, dg.module).?;
841 const field_ty = ty.unionFields().values()[index].ty;841 const field_ty = ty.unionFields().values()[index].ty;
842 const field_name = ty.unionFields().keys()[index];842 const field_name = ty.unionFields().keys()[index];
843 if (field_ty.hasRuntimeBits()) {843 if (field_ty.hasRuntimeBits()) {
...@@ -889,7 +889,7 @@ pub const DeclGen = struct {...@@ -889,7 +889,7 @@ pub const DeclGen = struct {
889 try w.writeAll("void");889 try w.writeAll("void");
890 }890 }
891 try w.writeAll(" ");891 try w.writeAll(" ");
892 try dg.renderDeclName(w, dg.decl);892 try dg.renderDeclName(w, dg.decl_index);
893 try w.writeAll("(");893 try w.writeAll("(");
894 const param_len = dg.decl.ty.fnParamLen();894 const param_len = dg.decl.ty.fnParamLen();
895895
...@@ -927,8 +927,7 @@ pub const DeclGen = struct {...@@ -927,8 +927,7 @@ pub const DeclGen = struct {
927 try bw.writeAll(" (*");927 try bw.writeAll(" (*");
928928
929 const name_start = buffer.items.len;929 const name_start = buffer.items.len;
930 const target = dg.module.getTarget();930 try bw.print("zig_F_{s})(", .{typeToCIdentifier(t, dg.module)});
931 try bw.print("zig_F_{s})(", .{typeToCIdentifier(t, target)});
932 const name_end = buffer.items.len - 2;931 const name_end = buffer.items.len - 2;
933932
934 const param_len = fn_info.param_types.len;933 const param_len = fn_info.param_types.len;
...@@ -982,11 +981,10 @@ pub const DeclGen = struct {...@@ -982,11 +981,10 @@ pub const DeclGen = struct {
982981
983 try bw.writeAll("; size_t len; } ");982 try bw.writeAll("; size_t len; } ");
984 const name_index = buffer.items.len;983 const name_index = buffer.items.len;
985 const target = dg.module.getTarget();
986 if (t.isConstPtr()) {984 if (t.isConstPtr()) {
987 try bw.print("zig_L_{s}", .{typeToCIdentifier(child_type, target)});985 try bw.print("zig_L_{s}", .{typeToCIdentifier(child_type, dg.module)});
988 } else {986 } else {
989 try bw.print("zig_M_{s}", .{typeToCIdentifier(child_type, target)});987 try bw.print("zig_M_{s}", .{typeToCIdentifier(child_type, dg.module)});
990 }988 }
991 if (ptr_sentinel) |s| {989 if (ptr_sentinel) |s| {
992 try bw.writeAll("_s_");990 try bw.writeAll("_s_");
...@@ -1009,7 +1007,7 @@ pub const DeclGen = struct {...@@ -1009,7 +1007,7 @@ pub const DeclGen = struct {
10091007
1010 fn renderStructTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {1008 fn renderStructTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
1011 const struct_obj = t.castTag(.@"struct").?.data; // Handle 0 bit types elsewhere.1009 const struct_obj = t.castTag(.@"struct").?.data; // Handle 0 bit types elsewhere.
1012 const fqn = try struct_obj.getFullyQualifiedName(dg.typedefs.allocator);1010 const fqn = try struct_obj.getFullyQualifiedName(dg.module);
1013 defer dg.typedefs.allocator.free(fqn);1011 defer dg.typedefs.allocator.free(fqn);
10141012
1015 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);1013 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
...@@ -1072,8 +1070,7 @@ pub const DeclGen = struct {...@@ -1072,8 +1070,7 @@ pub const DeclGen = struct {
1072 try buffer.appendSlice("} ");1070 try buffer.appendSlice("} ");
10731071
1074 const name_start = buffer.items.len;1072 const name_start = buffer.items.len;
1075 const target = dg.module.getTarget();1073 try writer.print("zig_T_{};\n", .{typeToCIdentifier(t, dg.module)});
1076 try writer.print("zig_T_{};\n", .{typeToCIdentifier(t, target)});
10771074
1078 const rendered = buffer.toOwnedSlice();1075 const rendered = buffer.toOwnedSlice();
1079 errdefer dg.typedefs.allocator.free(rendered);1076 errdefer dg.typedefs.allocator.free(rendered);
...@@ -1090,7 +1087,7 @@ pub const DeclGen = struct {...@@ -1090,7 +1087,7 @@ pub const DeclGen = struct {
10901087
1091 fn renderUnionTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {1088 fn renderUnionTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
1092 const union_ty = t.cast(Type.Payload.Union).?.data;1089 const union_ty = t.cast(Type.Payload.Union).?.data;
1093 const fqn = try union_ty.getFullyQualifiedName(dg.typedefs.allocator);1090 const fqn = try union_ty.getFullyQualifiedName(dg.module);
1094 defer dg.typedefs.allocator.free(fqn);1091 defer dg.typedefs.allocator.free(fqn);
10951092
1096 const target = dg.module.getTarget();1093 const target = dg.module.getTarget();
...@@ -1157,7 +1154,6 @@ pub const DeclGen = struct {...@@ -1157,7 +1154,6 @@ pub const DeclGen = struct {
1157 try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0);1154 try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0);
1158 try bw.writeAll("; uint16_t error; } ");1155 try bw.writeAll("; uint16_t error; } ");
1159 const name_index = buffer.items.len;1156 const name_index = buffer.items.len;
1160 const target = dg.module.getTarget();
1161 if (err_set_type.castTag(.error_set_inferred)) |inf_err_set_payload| {1157 if (err_set_type.castTag(.error_set_inferred)) |inf_err_set_payload| {
1162 const func = inf_err_set_payload.data.func;1158 const func = inf_err_set_payload.data.func;
1163 try bw.writeAll("zig_E_");1159 try bw.writeAll("zig_E_");
...@@ -1165,7 +1161,7 @@ pub const DeclGen = struct {...@@ -1165,7 +1161,7 @@ pub const DeclGen = struct {
1165 try bw.writeAll(";\n");1161 try bw.writeAll(";\n");
1166 } else {1162 } else {
1167 try bw.print("zig_E_{s}_{s};\n", .{1163 try bw.print("zig_E_{s}_{s};\n", .{
1168 typeToCIdentifier(err_set_type, target), typeToCIdentifier(child_type, target),1164 typeToCIdentifier(err_set_type, dg.module), typeToCIdentifier(child_type, dg.module),
1169 });1165 });
1170 }1166 }
11711167
...@@ -1195,8 +1191,7 @@ pub const DeclGen = struct {...@@ -1195,8 +1191,7 @@ pub const DeclGen = struct {
1195 try dg.renderType(bw, elem_type);1191 try dg.renderType(bw, elem_type);
11961192
1197 const name_start = buffer.items.len + 1;1193 const name_start = buffer.items.len + 1;
1198 const target = dg.module.getTarget();1194 try bw.print(" zig_A_{s}_{d}", .{ typeToCIdentifier(elem_type, dg.module), c_len });
1199 try bw.print(" zig_A_{s}_{d}", .{ typeToCIdentifier(elem_type, target), c_len });
1200 const name_end = buffer.items.len;1195 const name_end = buffer.items.len;
12011196
1202 try bw.print("[{d}];\n", .{c_len});1197 try bw.print("[{d}];\n", .{c_len});
...@@ -1224,8 +1219,7 @@ pub const DeclGen = struct {...@@ -1224,8 +1219,7 @@ pub const DeclGen = struct {
1224 try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0);1219 try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0);
1225 try bw.writeAll("; bool is_null; } ");1220 try bw.writeAll("; bool is_null; } ");
1226 const name_index = buffer.items.len;1221 const name_index = buffer.items.len;
1227 const target = dg.module.getTarget();1222 try bw.print("zig_Q_{s};\n", .{typeToCIdentifier(child_type, dg.module)});
1228 try bw.print("zig_Q_{s};\n", .{typeToCIdentifier(child_type, target)});
12291223
1230 const rendered = buffer.toOwnedSlice();1224 const rendered = buffer.toOwnedSlice();
1231 errdefer dg.typedefs.allocator.free(rendered);1225 errdefer dg.typedefs.allocator.free(rendered);
...@@ -1535,16 +1529,17 @@ pub const DeclGen = struct {...@@ -1535,16 +1529,17 @@ pub const DeclGen = struct {
1535 }1529 }
1536 }1530 }
15371531
1538 fn renderDeclName(dg: DeclGen, writer: anytype, decl: *Decl) !void {1532 fn renderDeclName(dg: DeclGen, writer: anytype, decl_index: Decl.Index) !void {
1539 decl.markAlive();1533 const decl = dg.module.declPtr(decl_index);
1534 dg.module.markDeclAlive(decl);
15401535
1541 if (dg.module.decl_exports.get(decl)) |exports| {1536 if (dg.module.decl_exports.get(decl_index)) |exports| {
1542 return writer.writeAll(exports[0].options.name);1537 return writer.writeAll(exports[0].options.name);
1543 } else if (decl.val.tag() == .extern_fn) {1538 } else if (decl.val.tag() == .extern_fn) {
1544 return writer.writeAll(mem.sliceTo(decl.name, 0));1539 return writer.writeAll(mem.sliceTo(decl.name, 0));
1545 } else {1540 } else {
1546 const gpa = dg.module.gpa;1541 const gpa = dg.module.gpa;
1547 const name = try decl.getFullyQualifiedName(gpa);1542 const name = try decl.getFullyQualifiedName(dg.module);
1548 defer gpa.free(name);1543 defer gpa.free(name);
1549 return writer.print("{ }", .{fmtIdent(name)});1544 return writer.print("{ }", .{fmtIdent(name)});
1550 }1545 }
...@@ -1616,7 +1611,11 @@ pub fn genDecl(o: *Object) !void {...@@ -1616,7 +1611,11 @@ pub fn genDecl(o: *Object) !void {
1616 try fwd_decl_writer.writeAll("zig_threadlocal ");1611 try fwd_decl_writer.writeAll("zig_threadlocal ");
1617 }1612 }
16181613
1619 const decl_c_value: CValue = if (is_global) .{ .bytes = mem.span(o.dg.decl.name) } else .{ .decl = o.dg.decl };1614 const decl_c_value: CValue = if (is_global) .{
1615 .bytes = mem.span(o.dg.decl.name),
1616 } else .{
1617 .decl = o.dg.decl_index,
1618 };
16201619
1621 try o.dg.renderTypeAndName(fwd_decl_writer, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align");1620 try o.dg.renderTypeAndName(fwd_decl_writer, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align");
1622 try fwd_decl_writer.writeAll(";\n");1621 try fwd_decl_writer.writeAll(";\n");
...@@ -1641,7 +1640,7 @@ pub fn genDecl(o: *Object) !void {...@@ -1641,7 +1640,7 @@ pub fn genDecl(o: *Object) !void {
1641 // TODO ask the Decl if it is const1640 // TODO ask the Decl if it is const
1642 // https://github.com/ziglang/zig/issues/75821641 // https://github.com/ziglang/zig/issues/7582
16431642
1644 const decl_c_value: CValue = .{ .decl = o.dg.decl };1643 const decl_c_value: CValue = .{ .decl = o.dg.decl_index };
1645 try o.dg.renderTypeAndName(writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align");1644 try o.dg.renderTypeAndName(writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align");
16461645
1647 try writer.writeAll(" = ");1646 try writer.writeAll(" = ");
...@@ -2234,13 +2233,12 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2234,13 +2233,12 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
2234 if (src_val_is_undefined)2233 if (src_val_is_undefined)
2235 return try airStoreUndefined(f, dest_ptr);2234 return try airStoreUndefined(f, dest_ptr);
22362235
2237 const target = f.object.dg.module.getTarget();
2238 const writer = f.object.writer();2236 const writer = f.object.writer();
2239 if (lhs_child_type.zigTypeTag() == .Array) {2237 if (lhs_child_type.zigTypeTag() == .Array) {
2240 // For this memcpy to safely work we need the rhs to have the same2238 // For this memcpy to safely work we need the rhs to have the same
2241 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).2239 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).
2242 const rhs_type = f.air.typeOf(bin_op.rhs);2240 const rhs_type = f.air.typeOf(bin_op.rhs);
2243 assert(rhs_type.eql(lhs_child_type, target));2241 assert(rhs_type.eql(lhs_child_type, f.object.dg.module));
22442242
2245 // If the source is a constant, writeCValue will emit a brace initialization2243 // If the source is a constant, writeCValue will emit a brace initialization
2246 // so work around this by initializing into new local.2244 // so work around this by initializing into new local.
...@@ -2780,7 +2778,8 @@ fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2780,7 +2778,8 @@ fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue {
2780 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;2778 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
2781 const writer = f.object.writer();2779 const writer = f.object.writer();
2782 const function = f.air.values[ty_pl.payload].castTag(.function).?.data;2780 const function = f.air.values[ty_pl.payload].castTag(.function).?.data;
2783 try writer.print("/* dbg func:{s} */\n", .{function.owner_decl.name});2781 const mod = f.object.dg.module;
2782 try writer.print("/* dbg func:{s} */\n", .{mod.declPtr(function.owner_decl).name});
2784 return CValue.none;2783 return CValue.none;
2785}2784}
27862785
src/codegen/llvm.zig+134-113
...@@ -161,6 +161,7 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![:0]u8 {...@@ -161,6 +161,7 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![:0]u8 {
161161
162pub const Object = struct {162pub const Object = struct {
163 gpa: Allocator,163 gpa: Allocator,
164 module: *Module,
164 llvm_module: *const llvm.Module,165 llvm_module: *const llvm.Module,
165 di_builder: ?*llvm.DIBuilder,166 di_builder: ?*llvm.DIBuilder,
166 /// One of these mappings:167 /// One of these mappings:
...@@ -181,7 +182,7 @@ pub const Object = struct {...@@ -181,7 +182,7 @@ pub const Object = struct {
181 /// version of the name and incorrectly get function not found in the llvm module.182 /// version of the name and incorrectly get function not found in the llvm module.
182 /// * it works for functions not all globals.183 /// * it works for functions not all globals.
183 /// Therefore, this table keeps track of the mapping.184 /// Therefore, this table keeps track of the mapping.
184 decl_map: std.AutoHashMapUnmanaged(*const Module.Decl, *const llvm.Value),185 decl_map: std.AutoHashMapUnmanaged(Module.Decl.Index, *const llvm.Value),
185 /// Maps Zig types to LLVM types. The table memory itself is backed by the GPA of186 /// Maps Zig types to LLVM types. The table memory itself is backed by the GPA of
186 /// the compiler, but the Type/Value memory here is backed by `type_map_arena`.187 /// the compiler, but the Type/Value memory here is backed by `type_map_arena`.
187 /// TODO we need to remove entries from this map in response to incremental compilation188 /// TODO we need to remove entries from this map in response to incremental compilation
...@@ -340,6 +341,7 @@ pub const Object = struct {...@@ -340,6 +341,7 @@ pub const Object = struct {
340341
341 return Object{342 return Object{
342 .gpa = gpa,343 .gpa = gpa,
344 .module = options.module.?,
343 .llvm_module = llvm_module,345 .llvm_module = llvm_module,
344 .di_map = .{},346 .di_map = .{},
345 .di_builder = opt_di_builder,347 .di_builder = opt_di_builder,
...@@ -568,18 +570,20 @@ pub const Object = struct {...@@ -568,18 +570,20 @@ pub const Object = struct {
568 air: Air,570 air: Air,
569 liveness: Liveness,571 liveness: Liveness,
570 ) !void {572 ) !void {
571 const decl = func.owner_decl;573 const decl_index = func.owner_decl;
574 const decl = module.declPtr(decl_index);
572575
573 var dg: DeclGen = .{576 var dg: DeclGen = .{
574 .context = o.context,577 .context = o.context,
575 .object = o,578 .object = o,
576 .module = module,579 .module = module,
580 .decl_index = decl_index,
577 .decl = decl,581 .decl = decl,
578 .err_msg = null,582 .err_msg = null,
579 .gpa = module.gpa,583 .gpa = module.gpa,
580 };584 };
581585
582 const llvm_func = try dg.resolveLlvmFunction(decl);586 const llvm_func = try dg.resolveLlvmFunction(decl_index);
583587
584 if (module.align_stack_fns.get(func)) |align_info| {588 if (module.align_stack_fns.get(func)) |align_info| {
585 dg.addFnAttrInt(llvm_func, "alignstack", align_info.alignment);589 dg.addFnAttrInt(llvm_func, "alignstack", align_info.alignment);
...@@ -632,7 +636,7 @@ pub const Object = struct {...@@ -632,7 +636,7 @@ pub const Object = struct {
632636
633 const line_number = decl.src_line + 1;637 const line_number = decl.src_line + 1;
634 const is_internal_linkage = decl.val.tag() != .extern_fn and638 const is_internal_linkage = decl.val.tag() != .extern_fn and
635 !dg.module.decl_exports.contains(decl);639 !dg.module.decl_exports.contains(decl_index);
636 const noret_bit: c_uint = if (fn_info.return_type.isNoReturn())640 const noret_bit: c_uint = if (fn_info.return_type.isNoReturn())
637 llvm.DIFlags.NoReturn641 llvm.DIFlags.NoReturn
638 else642 else
...@@ -684,48 +688,51 @@ pub const Object = struct {...@@ -684,48 +688,51 @@ pub const Object = struct {
684 fg.genBody(air.getMainBody()) catch |err| switch (err) {688 fg.genBody(air.getMainBody()) catch |err| switch (err) {
685 error.CodegenFail => {689 error.CodegenFail => {
686 decl.analysis = .codegen_failure;690 decl.analysis = .codegen_failure;
687 try module.failed_decls.put(module.gpa, decl, dg.err_msg.?);691 try module.failed_decls.put(module.gpa, decl_index, dg.err_msg.?);
688 dg.err_msg = null;692 dg.err_msg = null;
689 return;693 return;
690 },694 },
691 else => |e| return e,695 else => |e| return e,
692 };696 };
693697
694 const decl_exports = module.decl_exports.get(decl) orelse &[0]*Module.Export{};698 const decl_exports = module.decl_exports.get(decl_index) orelse &[0]*Module.Export{};
695 try o.updateDeclExports(module, decl, decl_exports);699 try o.updateDeclExports(module, decl_index, decl_exports);
696 }700 }
697701
698 pub fn updateDecl(self: *Object, module: *Module, decl: *Module.Decl) !void {702 pub fn updateDecl(self: *Object, module: *Module, decl_index: Module.Decl.Index) !void {
703 const decl = module.declPtr(decl_index);
699 var dg: DeclGen = .{704 var dg: DeclGen = .{
700 .context = self.context,705 .context = self.context,
701 .object = self,706 .object = self,
702 .module = module,707 .module = module,
703 .decl = decl,708 .decl = decl,
709 .decl_index = decl_index,
704 .err_msg = null,710 .err_msg = null,
705 .gpa = module.gpa,711 .gpa = module.gpa,
706 };712 };
707 dg.genDecl() catch |err| switch (err) {713 dg.genDecl() catch |err| switch (err) {
708 error.CodegenFail => {714 error.CodegenFail => {
709 decl.analysis = .codegen_failure;715 decl.analysis = .codegen_failure;
710 try module.failed_decls.put(module.gpa, decl, dg.err_msg.?);716 try module.failed_decls.put(module.gpa, decl_index, dg.err_msg.?);
711 dg.err_msg = null;717 dg.err_msg = null;
712 return;718 return;
713 },719 },
714 else => |e| return e,720 else => |e| return e,
715 };721 };
716 const decl_exports = module.decl_exports.get(decl) orelse &[0]*Module.Export{};722 const decl_exports = module.decl_exports.get(decl_index) orelse &[0]*Module.Export{};
717 try self.updateDeclExports(module, decl, decl_exports);723 try self.updateDeclExports(module, decl_index, decl_exports);
718 }724 }
719725
720 pub fn updateDeclExports(726 pub fn updateDeclExports(
721 self: *Object,727 self: *Object,
722 module: *const Module,728 module: *Module,
723 decl: *const Module.Decl,729 decl_index: Module.Decl.Index,
724 exports: []const *Module.Export,730 exports: []const *Module.Export,
725 ) !void {731 ) !void {
726 // If the module does not already have the function, we ignore this function call732 // If the module does not already have the function, we ignore this function call
727 // because we call `updateDeclExports` at the end of `updateFunc` and `updateDecl`.733 // because we call `updateDeclExports` at the end of `updateFunc` and `updateDecl`.
728 const llvm_global = self.decl_map.get(decl) orelse return;734 const llvm_global = self.decl_map.get(decl_index) orelse return;
735 const decl = module.declPtr(decl_index);
729 if (decl.isExtern()) {736 if (decl.isExtern()) {
730 llvm_global.setValueName(decl.name);737 llvm_global.setValueName(decl.name);
731 llvm_global.setUnnamedAddr(.False);738 llvm_global.setUnnamedAddr(.False);
...@@ -798,7 +805,7 @@ pub const Object = struct {...@@ -798,7 +805,7 @@ pub const Object = struct {
798 }805 }
799 }806 }
800 } else {807 } else {
801 const fqn = try decl.getFullyQualifiedName(module.gpa);808 const fqn = try decl.getFullyQualifiedName(module);
802 defer module.gpa.free(fqn);809 defer module.gpa.free(fqn);
803 llvm_global.setValueName2(fqn.ptr, fqn.len);810 llvm_global.setValueName2(fqn.ptr, fqn.len);
804 llvm_global.setLinkage(.Internal);811 llvm_global.setLinkage(.Internal);
...@@ -814,8 +821,8 @@ pub const Object = struct {...@@ -814,8 +821,8 @@ pub const Object = struct {
814 }821 }
815 }822 }
816823
817 pub fn freeDecl(self: *Object, decl: *Module.Decl) void {824 pub fn freeDecl(self: *Object, decl_index: Module.Decl.Index) void {
818 const llvm_value = self.decl_map.get(decl) orelse return;825 const llvm_value = self.decl_map.get(decl_index) orelse return;
819 llvm_value.deleteGlobal();826 llvm_value.deleteGlobal();
820 }827 }
821828
...@@ -847,7 +854,7 @@ pub const Object = struct {...@@ -847,7 +854,7 @@ pub const Object = struct {
847 const gpa = o.gpa;854 const gpa = o.gpa;
848 // Be careful not to reference this `gop` variable after any recursive calls855 // Be careful not to reference this `gop` variable after any recursive calls
849 // to `lowerDebugType`.856 // to `lowerDebugType`.
850 const gop = try o.di_type_map.getOrPutContext(gpa, ty, .{ .target = o.target });857 const gop = try o.di_type_map.getOrPutContext(gpa, ty, .{ .mod = o.module });
851 if (gop.found_existing) {858 if (gop.found_existing) {
852 const annotated = gop.value_ptr.*;859 const annotated = gop.value_ptr.*;
853 const di_type = annotated.toDIType();860 const di_type = annotated.toDIType();
...@@ -860,7 +867,7 @@ pub const Object = struct {...@@ -860,7 +867,7 @@ pub const Object = struct {
860 };867 };
861 return o.lowerDebugTypeImpl(entry, resolve, di_type);868 return o.lowerDebugTypeImpl(entry, resolve, di_type);
862 }869 }
863 errdefer assert(o.di_type_map.orderedRemoveContext(ty, .{ .target = o.target }));870 errdefer assert(o.di_type_map.orderedRemoveContext(ty, .{ .mod = o.module }));
864 // The Type memory is ephemeral; since we want to store a longer-lived871 // The Type memory is ephemeral; since we want to store a longer-lived
865 // reference, we need to copy it here.872 // reference, we need to copy it here.
866 gop.key_ptr.* = try ty.copy(o.type_map_arena.allocator());873 gop.key_ptr.* = try ty.copy(o.type_map_arena.allocator());
...@@ -891,7 +898,7 @@ pub const Object = struct {...@@ -891,7 +898,7 @@ pub const Object = struct {
891 .Int => {898 .Int => {
892 const info = ty.intInfo(target);899 const info = ty.intInfo(target);
893 assert(info.bits != 0);900 assert(info.bits != 0);
894 const name = try ty.nameAlloc(gpa, target);901 const name = try ty.nameAlloc(gpa, o.module);
895 defer gpa.free(name);902 defer gpa.free(name);
896 const dwarf_encoding: c_uint = switch (info.signedness) {903 const dwarf_encoding: c_uint = switch (info.signedness) {
897 .signed => DW.ATE.signed,904 .signed => DW.ATE.signed,
...@@ -902,13 +909,14 @@ pub const Object = struct {...@@ -902,13 +909,14 @@ pub const Object = struct {
902 return di_type;909 return di_type;
903 },910 },
904 .Enum => {911 .Enum => {
905 const owner_decl = ty.getOwnerDecl();912 const owner_decl_index = ty.getOwnerDecl();
913 const owner_decl = o.module.declPtr(owner_decl_index);
906914
907 if (!ty.hasRuntimeBitsIgnoreComptime()) {915 if (!ty.hasRuntimeBitsIgnoreComptime()) {
908 const enum_di_ty = try o.makeEmptyNamespaceDIType(owner_decl);916 const enum_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
909 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`917 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
910 // means we can't use `gop` anymore.918 // means we can't use `gop` anymore.
911 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty), .{ .target = o.target });919 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty), .{ .mod = o.module });
912 return enum_di_ty;920 return enum_di_ty;
913 }921 }
914922
...@@ -938,7 +946,7 @@ pub const Object = struct {...@@ -938,7 +946,7 @@ pub const Object = struct {
938 const di_file = try o.getDIFile(gpa, owner_decl.src_namespace.file_scope);946 const di_file = try o.getDIFile(gpa, owner_decl.src_namespace.file_scope);
939 const di_scope = try o.namespaceToDebugScope(owner_decl.src_namespace);947 const di_scope = try o.namespaceToDebugScope(owner_decl.src_namespace);
940948
941 const name = try ty.nameAlloc(gpa, target);949 const name = try ty.nameAlloc(gpa, o.module);
942 defer gpa.free(name);950 defer gpa.free(name);
943 var buffer: Type.Payload.Bits = undefined;951 var buffer: Type.Payload.Bits = undefined;
944 const int_ty = ty.intTagType(&buffer);952 const int_ty = ty.intTagType(&buffer);
...@@ -956,12 +964,12 @@ pub const Object = struct {...@@ -956,12 +964,12 @@ pub const Object = struct {
956 "",964 "",
957 );965 );
958 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.966 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
959 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty), .{ .target = o.target });967 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty), .{ .mod = o.module });
960 return enum_di_ty;968 return enum_di_ty;
961 },969 },
962 .Float => {970 .Float => {
963 const bits = ty.floatBits(target);971 const bits = ty.floatBits(target);
964 const name = try ty.nameAlloc(gpa, target);972 const name = try ty.nameAlloc(gpa, o.module);
965 defer gpa.free(name);973 defer gpa.free(name);
966 const di_type = dib.createBasicType(name, bits, DW.ATE.float);974 const di_type = dib.createBasicType(name, bits, DW.ATE.float);
967 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);975 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
...@@ -1009,7 +1017,7 @@ pub const Object = struct {...@@ -1009,7 +1017,7 @@ pub const Object = struct {
1009 const bland_ptr_ty = Type.initPayload(&payload.base);1017 const bland_ptr_ty = Type.initPayload(&payload.base);
1010 const ptr_di_ty = try o.lowerDebugType(bland_ptr_ty, resolve);1018 const ptr_di_ty = try o.lowerDebugType(bland_ptr_ty, resolve);
1011 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1019 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1012 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.init(ptr_di_ty, resolve), .{ .target = o.target });1020 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.init(ptr_di_ty, resolve), .{ .mod = o.module });
1013 return ptr_di_ty;1021 return ptr_di_ty;
1014 }1022 }
10151023
...@@ -1018,7 +1026,7 @@ pub const Object = struct {...@@ -1018,7 +1026,7 @@ pub const Object = struct {
1018 const ptr_ty = ty.slicePtrFieldType(&buf);1026 const ptr_ty = ty.slicePtrFieldType(&buf);
1019 const len_ty = Type.usize;1027 const len_ty = Type.usize;
10201028
1021 const name = try ty.nameAlloc(gpa, target);1029 const name = try ty.nameAlloc(gpa, o.module);
1022 defer gpa.free(name);1030 defer gpa.free(name);
1023 const di_file: ?*llvm.DIFile = null;1031 const di_file: ?*llvm.DIFile = null;
1024 const line = 0;1032 const line = 0;
...@@ -1089,12 +1097,12 @@ pub const Object = struct {...@@ -1089,12 +1097,12 @@ pub const Object = struct {
1089 );1097 );
1090 dib.replaceTemporary(fwd_decl, full_di_ty);1098 dib.replaceTemporary(fwd_decl, full_di_ty);
1091 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1099 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1092 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });1100 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .mod = o.module });
1093 return full_di_ty;1101 return full_di_ty;
1094 }1102 }
10951103
1096 const elem_di_ty = try o.lowerDebugType(ptr_info.pointee_type, .fwd);1104 const elem_di_ty = try o.lowerDebugType(ptr_info.pointee_type, .fwd);
1097 const name = try ty.nameAlloc(gpa, target);1105 const name = try ty.nameAlloc(gpa, o.module);
1098 defer gpa.free(name);1106 defer gpa.free(name);
1099 const ptr_di_ty = dib.createPointerType(1107 const ptr_di_ty = dib.createPointerType(
1100 elem_di_ty,1108 elem_di_ty,
...@@ -1103,7 +1111,7 @@ pub const Object = struct {...@@ -1103,7 +1111,7 @@ pub const Object = struct {
1103 name,1111 name,
1104 );1112 );
1105 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1113 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1106 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty), .{ .target = o.target });1114 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty), .{ .mod = o.module });
1107 return ptr_di_ty;1115 return ptr_di_ty;
1108 },1116 },
1109 .Opaque => {1117 .Opaque => {
...@@ -1112,9 +1120,10 @@ pub const Object = struct {...@@ -1112,9 +1120,10 @@ pub const Object = struct {
1112 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);1120 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
1113 return di_ty;1121 return di_ty;
1114 }1122 }
1115 const name = try ty.nameAlloc(gpa, target);1123 const name = try ty.nameAlloc(gpa, o.module);
1116 defer gpa.free(name);1124 defer gpa.free(name);
1117 const owner_decl = ty.getOwnerDecl();1125 const owner_decl_index = ty.getOwnerDecl();
1126 const owner_decl = o.module.declPtr(owner_decl_index);
1118 const opaque_di_ty = dib.createForwardDeclType(1127 const opaque_di_ty = dib.createForwardDeclType(
1119 DW.TAG.structure_type,1128 DW.TAG.structure_type,
1120 name,1129 name,
...@@ -1124,7 +1133,7 @@ pub const Object = struct {...@@ -1124,7 +1133,7 @@ pub const Object = struct {
1124 );1133 );
1125 // The recursive call to `lowerDebugType` va `namespaceToDebugScope`1134 // The recursive call to `lowerDebugType` va `namespaceToDebugScope`
1126 // means we can't use `gop` anymore.1135 // means we can't use `gop` anymore.
1127 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(opaque_di_ty), .{ .target = o.target });1136 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(opaque_di_ty), .{ .mod = o.module });
1128 return opaque_di_ty;1137 return opaque_di_ty;
1129 },1138 },
1130 .Array => {1139 .Array => {
...@@ -1135,7 +1144,7 @@ pub const Object = struct {...@@ -1135,7 +1144,7 @@ pub const Object = struct {
1135 @intCast(c_int, ty.arrayLen()),1144 @intCast(c_int, ty.arrayLen()),
1136 );1145 );
1137 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1146 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1138 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(array_di_ty), .{ .target = o.target });1147 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(array_di_ty), .{ .mod = o.module });
1139 return array_di_ty;1148 return array_di_ty;
1140 },1149 },
1141 .Vector => {1150 .Vector => {
...@@ -1146,11 +1155,11 @@ pub const Object = struct {...@@ -1146,11 +1155,11 @@ pub const Object = struct {
1146 ty.vectorLen(),1155 ty.vectorLen(),
1147 );1156 );
1148 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1157 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1149 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(vector_di_ty), .{ .target = o.target });1158 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(vector_di_ty), .{ .mod = o.module });
1150 return vector_di_ty;1159 return vector_di_ty;
1151 },1160 },
1152 .Optional => {1161 .Optional => {
1153 const name = try ty.nameAlloc(gpa, target);1162 const name = try ty.nameAlloc(gpa, o.module);
1154 defer gpa.free(name);1163 defer gpa.free(name);
1155 var buf: Type.Payload.ElemType = undefined;1164 var buf: Type.Payload.ElemType = undefined;
1156 const child_ty = ty.optionalChild(&buf);1165 const child_ty = ty.optionalChild(&buf);
...@@ -1162,7 +1171,7 @@ pub const Object = struct {...@@ -1162,7 +1171,7 @@ pub const Object = struct {
1162 if (ty.isPtrLikeOptional()) {1171 if (ty.isPtrLikeOptional()) {
1163 const ptr_di_ty = try o.lowerDebugType(child_ty, resolve);1172 const ptr_di_ty = try o.lowerDebugType(child_ty, resolve);
1164 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1173 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1165 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty), .{ .target = o.target });1174 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty), .{ .mod = o.module });
1166 return ptr_di_ty;1175 return ptr_di_ty;
1167 }1176 }
11681177
...@@ -1235,7 +1244,7 @@ pub const Object = struct {...@@ -1235,7 +1244,7 @@ pub const Object = struct {
1235 );1244 );
1236 dib.replaceTemporary(fwd_decl, full_di_ty);1245 dib.replaceTemporary(fwd_decl, full_di_ty);
1237 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1246 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1238 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });1247 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .mod = o.module });
1239 return full_di_ty;1248 return full_di_ty;
1240 },1249 },
1241 .ErrorUnion => {1250 .ErrorUnion => {
...@@ -1244,10 +1253,10 @@ pub const Object = struct {...@@ -1244,10 +1253,10 @@ pub const Object = struct {
1244 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {1253 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
1245 const err_set_di_ty = try o.lowerDebugType(err_set_ty, .full);1254 const err_set_di_ty = try o.lowerDebugType(err_set_ty, .full);
1246 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1255 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1247 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(err_set_di_ty), .{ .target = o.target });1256 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(err_set_di_ty), .{ .mod = o.module });
1248 return err_set_di_ty;1257 return err_set_di_ty;
1249 }1258 }
1250 const name = try ty.nameAlloc(gpa, target);1259 const name = try ty.nameAlloc(gpa, o.module);
1251 defer gpa.free(name);1260 defer gpa.free(name);
1252 const di_file: ?*llvm.DIFile = null;1261 const di_file: ?*llvm.DIFile = null;
1253 const line = 0;1262 const line = 0;
...@@ -1332,7 +1341,7 @@ pub const Object = struct {...@@ -1332,7 +1341,7 @@ pub const Object = struct {
1332 );1341 );
1333 dib.replaceTemporary(fwd_decl, full_di_ty);1342 dib.replaceTemporary(fwd_decl, full_di_ty);
1334 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1343 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1335 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });1344 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .mod = o.module });
1336 return full_di_ty;1345 return full_di_ty;
1337 },1346 },
1338 .ErrorSet => {1347 .ErrorSet => {
...@@ -1344,7 +1353,7 @@ pub const Object = struct {...@@ -1344,7 +1353,7 @@ pub const Object = struct {
1344 },1353 },
1345 .Struct => {1354 .Struct => {
1346 const compile_unit_scope = o.di_compile_unit.?.toScope();1355 const compile_unit_scope = o.di_compile_unit.?.toScope();
1347 const name = try ty.nameAlloc(gpa, target);1356 const name = try ty.nameAlloc(gpa, o.module);
1348 defer gpa.free(name);1357 defer gpa.free(name);
13491358
1350 if (ty.castTag(.@"struct")) |payload| {1359 if (ty.castTag(.@"struct")) |payload| {
...@@ -1431,7 +1440,7 @@ pub const Object = struct {...@@ -1431,7 +1440,7 @@ pub const Object = struct {
1431 );1440 );
1432 dib.replaceTemporary(fwd_decl, full_di_ty);1441 dib.replaceTemporary(fwd_decl, full_di_ty);
1433 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1442 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1434 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });1443 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .mod = o.module });
1435 return full_di_ty;1444 return full_di_ty;
1436 }1445 }
14371446
...@@ -1445,23 +1454,23 @@ pub const Object = struct {...@@ -1445,23 +1454,23 @@ pub const Object = struct {
1445 // into. Therefore we can satisfy this by making an empty namespace,1454 // into. Therefore we can satisfy this by making an empty namespace,
1446 // rather than changing the frontend to unnecessarily resolve the1455 // rather than changing the frontend to unnecessarily resolve the
1447 // struct field types.1456 // struct field types.
1448 const owner_decl = ty.getOwnerDecl();1457 const owner_decl_index = ty.getOwnerDecl();
1449 const struct_di_ty = try o.makeEmptyNamespaceDIType(owner_decl);1458 const struct_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
1450 dib.replaceTemporary(fwd_decl, struct_di_ty);1459 dib.replaceTemporary(fwd_decl, struct_di_ty);
1451 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`1460 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
1452 // means we can't use `gop` anymore.1461 // means we can't use `gop` anymore.
1453 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty), .{ .target = o.target });1462 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty), .{ .mod = o.module });
1454 return struct_di_ty;1463 return struct_di_ty;
1455 }1464 }
1456 }1465 }
14571466
1458 if (!ty.hasRuntimeBitsIgnoreComptime()) {1467 if (!ty.hasRuntimeBitsIgnoreComptime()) {
1459 const owner_decl = ty.getOwnerDecl();1468 const owner_decl_index = ty.getOwnerDecl();
1460 const struct_di_ty = try o.makeEmptyNamespaceDIType(owner_decl);1469 const struct_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
1461 dib.replaceTemporary(fwd_decl, struct_di_ty);1470 dib.replaceTemporary(fwd_decl, struct_di_ty);
1462 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`1471 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
1463 // means we can't use `gop` anymore.1472 // means we can't use `gop` anymore.
1464 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty), .{ .target = o.target });1473 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty), .{ .mod = o.module });
1465 return struct_di_ty;1474 return struct_di_ty;
1466 }1475 }
14671476
...@@ -1516,14 +1525,14 @@ pub const Object = struct {...@@ -1516,14 +1525,14 @@ pub const Object = struct {
1516 );1525 );
1517 dib.replaceTemporary(fwd_decl, full_di_ty);1526 dib.replaceTemporary(fwd_decl, full_di_ty);
1518 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1527 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1519 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });1528 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .mod = o.module });
1520 return full_di_ty;1529 return full_di_ty;
1521 },1530 },
1522 .Union => {1531 .Union => {
1523 const compile_unit_scope = o.di_compile_unit.?.toScope();1532 const compile_unit_scope = o.di_compile_unit.?.toScope();
1524 const owner_decl = ty.getOwnerDecl();1533 const owner_decl_index = ty.getOwnerDecl();
15251534
1526 const name = try ty.nameAlloc(gpa, target);1535 const name = try ty.nameAlloc(gpa, o.module);
1527 defer gpa.free(name);1536 defer gpa.free(name);
15281537
1529 const fwd_decl = opt_fwd_decl orelse blk: {1538 const fwd_decl = opt_fwd_decl orelse blk: {
...@@ -1540,11 +1549,11 @@ pub const Object = struct {...@@ -1540,11 +1549,11 @@ pub const Object = struct {
1540 };1549 };
15411550
1542 if (!ty.hasRuntimeBitsIgnoreComptime()) {1551 if (!ty.hasRuntimeBitsIgnoreComptime()) {
1543 const union_di_ty = try o.makeEmptyNamespaceDIType(owner_decl);1552 const union_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
1544 dib.replaceTemporary(fwd_decl, union_di_ty);1553 dib.replaceTemporary(fwd_decl, union_di_ty);
1545 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`1554 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
1546 // means we can't use `gop` anymore.1555 // means we can't use `gop` anymore.
1547 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(union_di_ty), .{ .target = o.target });1556 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(union_di_ty), .{ .mod = o.module });
1548 return union_di_ty;1557 return union_di_ty;
1549 }1558 }
15501559
...@@ -1572,7 +1581,7 @@ pub const Object = struct {...@@ -1572,7 +1581,7 @@ pub const Object = struct {
1572 dib.replaceTemporary(fwd_decl, full_di_ty);1581 dib.replaceTemporary(fwd_decl, full_di_ty);
1573 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`1582 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
1574 // means we can't use `gop` anymore.1583 // means we can't use `gop` anymore.
1575 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });1584 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .mod = o.module });
1576 return full_di_ty;1585 return full_di_ty;
1577 }1586 }
15781587
...@@ -1626,7 +1635,7 @@ pub const Object = struct {...@@ -1626,7 +1635,7 @@ pub const Object = struct {
1626 if (layout.tag_size == 0) {1635 if (layout.tag_size == 0) {
1627 dib.replaceTemporary(fwd_decl, union_di_ty);1636 dib.replaceTemporary(fwd_decl, union_di_ty);
1628 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1637 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1629 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(union_di_ty), .{ .target = o.target });1638 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(union_di_ty), .{ .mod = o.module });
1630 return union_di_ty;1639 return union_di_ty;
1631 }1640 }
16321641
...@@ -1685,7 +1694,7 @@ pub const Object = struct {...@@ -1685,7 +1694,7 @@ pub const Object = struct {
1685 );1694 );
1686 dib.replaceTemporary(fwd_decl, full_di_ty);1695 dib.replaceTemporary(fwd_decl, full_di_ty);
1687 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1696 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1688 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });1697 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .mod = o.module });
1689 return full_di_ty;1698 return full_di_ty;
1690 },1699 },
1691 .Fn => {1700 .Fn => {
...@@ -1733,7 +1742,7 @@ pub const Object = struct {...@@ -1733,7 +1742,7 @@ pub const Object = struct {
1733 0,1742 0,
1734 );1743 );
1735 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1744 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1736 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(fn_di_ty), .{ .target = o.target });1745 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(fn_di_ty), .{ .mod = o.module });
1737 return fn_di_ty;1746 return fn_di_ty;
1738 },1747 },
1739 .ComptimeInt => unreachable,1748 .ComptimeInt => unreachable,
...@@ -1762,7 +1771,8 @@ pub const Object = struct {...@@ -1762,7 +1771,8 @@ pub const Object = struct {
1762 /// This is to be used instead of void for debug info types, to avoid tripping1771 /// This is to be used instead of void for debug info types, to avoid tripping
1763 /// Assertion `!isa<DIType>(Scope) && "shouldn't make a namespace scope for a type"'1772 /// Assertion `!isa<DIType>(Scope) && "shouldn't make a namespace scope for a type"'
1764 /// when targeting CodeView (Windows).1773 /// when targeting CodeView (Windows).
1765 fn makeEmptyNamespaceDIType(o: *Object, decl: *const Module.Decl) !*llvm.DIType {1774 fn makeEmptyNamespaceDIType(o: *Object, decl_index: Module.Decl.Index) !*llvm.DIType {
1775 const decl = o.module.declPtr(decl_index);
1766 const fields: [0]*llvm.DIType = .{};1776 const fields: [0]*llvm.DIType = .{};
1767 return o.di_builder.?.createStructType(1777 return o.di_builder.?.createStructType(
1768 try o.namespaceToDebugScope(decl.src_namespace),1778 try o.namespaceToDebugScope(decl.src_namespace),
...@@ -1787,6 +1797,7 @@ pub const DeclGen = struct {...@@ -1787,6 +1797,7 @@ pub const DeclGen = struct {
1787 object: *Object,1797 object: *Object,
1788 module: *Module,1798 module: *Module,
1789 decl: *Module.Decl,1799 decl: *Module.Decl,
1800 decl_index: Module.Decl.Index,
1790 gpa: Allocator,1801 gpa: Allocator,
1791 err_msg: ?*Module.ErrorMsg,1802 err_msg: ?*Module.ErrorMsg,
17921803
...@@ -1804,6 +1815,7 @@ pub const DeclGen = struct {...@@ -1804,6 +1815,7 @@ pub const DeclGen = struct {
18041815
1805 fn genDecl(dg: *DeclGen) !void {1816 fn genDecl(dg: *DeclGen) !void {
1806 const decl = dg.decl;1817 const decl = dg.decl;
1818 const decl_index = dg.decl_index;
1807 assert(decl.has_tv);1819 assert(decl.has_tv);
18081820
1809 log.debug("gen: {s} type: {}, value: {}", .{1821 log.debug("gen: {s} type: {}, value: {}", .{
...@@ -1817,7 +1829,7 @@ pub const DeclGen = struct {...@@ -1817,7 +1829,7 @@ pub const DeclGen = struct {
1817 _ = try dg.resolveLlvmFunction(extern_fn.data.owner_decl);1829 _ = try dg.resolveLlvmFunction(extern_fn.data.owner_decl);
1818 } else {1830 } else {
1819 const target = dg.module.getTarget();1831 const target = dg.module.getTarget();
1820 var global = try dg.resolveGlobalDecl(decl);1832 var global = try dg.resolveGlobalDecl(decl_index);
1821 global.setAlignment(decl.getAlignment(target));1833 global.setAlignment(decl.getAlignment(target));
1822 assert(decl.has_tv);1834 assert(decl.has_tv);
1823 const init_val = if (decl.val.castTag(.variable)) |payload| init_val: {1835 const init_val = if (decl.val.castTag(.variable)) |payload| init_val: {
...@@ -1858,7 +1870,7 @@ pub const DeclGen = struct {...@@ -1858,7 +1870,7 @@ pub const DeclGen = struct {
1858 // old uses.1870 // old uses.
1859 const new_global_ptr = new_global.constBitCast(global.typeOf());1871 const new_global_ptr = new_global.constBitCast(global.typeOf());
1860 global.replaceAllUsesWith(new_global_ptr);1872 global.replaceAllUsesWith(new_global_ptr);
1861 dg.object.decl_map.putAssumeCapacity(decl, new_global);1873 dg.object.decl_map.putAssumeCapacity(decl_index, new_global);
1862 new_global.takeName(global);1874 new_global.takeName(global);
1863 global.deleteGlobal();1875 global.deleteGlobal();
1864 global = new_global;1876 global = new_global;
...@@ -1869,7 +1881,7 @@ pub const DeclGen = struct {...@@ -1869,7 +1881,7 @@ pub const DeclGen = struct {
1869 const di_file = try dg.object.getDIFile(dg.gpa, decl.src_namespace.file_scope);1881 const di_file = try dg.object.getDIFile(dg.gpa, decl.src_namespace.file_scope);
18701882
1871 const line_number = decl.src_line + 1;1883 const line_number = decl.src_line + 1;
1872 const is_internal_linkage = !dg.module.decl_exports.contains(decl);1884 const is_internal_linkage = !dg.module.decl_exports.contains(decl_index);
1873 const di_global = dib.createGlobalVariable(1885 const di_global = dib.createGlobalVariable(
1874 di_file.toScope(),1886 di_file.toScope(),
1875 decl.name,1887 decl.name,
...@@ -1888,12 +1900,10 @@ pub const DeclGen = struct {...@@ -1888,12 +1900,10 @@ pub const DeclGen = struct {
1888 /// If the llvm function does not exist, create it.1900 /// If the llvm function does not exist, create it.
1889 /// Note that this can be called before the function's semantic analysis has1901 /// Note that this can be called before the function's semantic analysis has
1890 /// completed, so if any attributes rely on that, they must be done in updateFunc, not here.1902 /// completed, so if any attributes rely on that, they must be done in updateFunc, not here.
1891 fn resolveLlvmFunction(dg: *DeclGen, decl: *Module.Decl) !*const llvm.Value {1903 fn resolveLlvmFunction(dg: *DeclGen, decl_index: Module.Decl.Index) !*const llvm.Value {
1892 return dg.resolveLlvmFunctionExtra(decl, decl.ty);1904 const decl = dg.module.declPtr(decl_index);
1893 }1905 const zig_fn_type = decl.ty;
18941906 const gop = try dg.object.decl_map.getOrPut(dg.gpa, decl_index);
1895 fn resolveLlvmFunctionExtra(dg: *DeclGen, decl: *Module.Decl, zig_fn_type: Type) !*const llvm.Value {
1896 const gop = try dg.object.decl_map.getOrPut(dg.gpa, decl);
1897 if (gop.found_existing) return gop.value_ptr.*;1907 if (gop.found_existing) return gop.value_ptr.*;
18981908
1899 assert(decl.has_tv);1909 assert(decl.has_tv);
...@@ -1903,7 +1913,7 @@ pub const DeclGen = struct {...@@ -1903,7 +1913,7 @@ pub const DeclGen = struct {
19031913
1904 const fn_type = try dg.llvmType(zig_fn_type);1914 const fn_type = try dg.llvmType(zig_fn_type);
19051915
1906 const fqn = try decl.getFullyQualifiedName(dg.gpa);1916 const fqn = try decl.getFullyQualifiedName(dg.module);
1907 defer dg.gpa.free(fqn);1917 defer dg.gpa.free(fqn);
19081918
1909 const llvm_addrspace = dg.llvmAddressSpace(decl.@"addrspace");1919 const llvm_addrspace = dg.llvmAddressSpace(decl.@"addrspace");
...@@ -1996,12 +2006,13 @@ pub const DeclGen = struct {...@@ -1996,12 +2006,13 @@ pub const DeclGen = struct {
1996 // TODO add target-cpu and target-features fn attributes2006 // TODO add target-cpu and target-features fn attributes
1997 }2007 }
19982008
1999 fn resolveGlobalDecl(dg: *DeclGen, decl: *Module.Decl) Error!*const llvm.Value {2009 fn resolveGlobalDecl(dg: *DeclGen, decl_index: Module.Decl.Index) Error!*const llvm.Value {
2000 const gop = try dg.object.decl_map.getOrPut(dg.gpa, decl);2010 const gop = try dg.object.decl_map.getOrPut(dg.gpa, decl_index);
2001 if (gop.found_existing) return gop.value_ptr.*;2011 if (gop.found_existing) return gop.value_ptr.*;
2002 errdefer assert(dg.object.decl_map.remove(decl));2012 errdefer assert(dg.object.decl_map.remove(decl_index));
20032013
2004 const fqn = try decl.getFullyQualifiedName(dg.gpa);2014 const decl = dg.module.declPtr(decl_index);
2015 const fqn = try decl.getFullyQualifiedName(dg.module);
2005 defer dg.gpa.free(fqn);2016 defer dg.gpa.free(fqn);
20062017
2007 const llvm_type = try dg.llvmType(decl.ty);2018 const llvm_type = try dg.llvmType(decl.ty);
...@@ -2122,7 +2133,7 @@ pub const DeclGen = struct {...@@ -2122,7 +2133,7 @@ pub const DeclGen = struct {
2122 },2133 },
2123 .Opaque => switch (t.tag()) {2134 .Opaque => switch (t.tag()) {
2124 .@"opaque" => {2135 .@"opaque" => {
2125 const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .target = target });2136 const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = dg.module });
2126 if (gop.found_existing) return gop.value_ptr.*;2137 if (gop.found_existing) return gop.value_ptr.*;
21272138
2128 // The Type memory is ephemeral; since we want to store a longer-lived2139 // The Type memory is ephemeral; since we want to store a longer-lived
...@@ -2130,7 +2141,7 @@ pub const DeclGen = struct {...@@ -2130,7 +2141,7 @@ pub const DeclGen = struct {
2130 gop.key_ptr.* = try t.copy(dg.object.type_map_arena.allocator());2141 gop.key_ptr.* = try t.copy(dg.object.type_map_arena.allocator());
21312142
2132 const opaque_obj = t.castTag(.@"opaque").?.data;2143 const opaque_obj = t.castTag(.@"opaque").?.data;
2133 const name = try opaque_obj.getFullyQualifiedName(gpa);2144 const name = try opaque_obj.getFullyQualifiedName(dg.module);
2134 defer gpa.free(name);2145 defer gpa.free(name);
21352146
2136 const llvm_struct_ty = dg.context.structCreateNamed(name);2147 const llvm_struct_ty = dg.context.structCreateNamed(name);
...@@ -2191,7 +2202,7 @@ pub const DeclGen = struct {...@@ -2191,7 +2202,7 @@ pub const DeclGen = struct {
2191 return dg.context.intType(16);2202 return dg.context.intType(16);
2192 },2203 },
2193 .Struct => {2204 .Struct => {
2194 const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .target = target });2205 const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = dg.module });
2195 if (gop.found_existing) return gop.value_ptr.*;2206 if (gop.found_existing) return gop.value_ptr.*;
21962207
2197 // The Type memory is ephemeral; since we want to store a longer-lived2208 // The Type memory is ephemeral; since we want to store a longer-lived
...@@ -2260,7 +2271,7 @@ pub const DeclGen = struct {...@@ -2260,7 +2271,7 @@ pub const DeclGen = struct {
2260 return int_llvm_ty;2271 return int_llvm_ty;
2261 }2272 }
22622273
2263 const name = try struct_obj.getFullyQualifiedName(gpa);2274 const name = try struct_obj.getFullyQualifiedName(dg.module);
2264 defer gpa.free(name);2275 defer gpa.free(name);
22652276
2266 const llvm_struct_ty = dg.context.structCreateNamed(name);2277 const llvm_struct_ty = dg.context.structCreateNamed(name);
...@@ -2314,7 +2325,7 @@ pub const DeclGen = struct {...@@ -2314,7 +2325,7 @@ pub const DeclGen = struct {
2314 return llvm_struct_ty;2325 return llvm_struct_ty;
2315 },2326 },
2316 .Union => {2327 .Union => {
2317 const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .target = target });2328 const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = dg.module });
2318 if (gop.found_existing) return gop.value_ptr.*;2329 if (gop.found_existing) return gop.value_ptr.*;
23192330
2320 // The Type memory is ephemeral; since we want to store a longer-lived2331 // The Type memory is ephemeral; since we want to store a longer-lived
...@@ -2330,7 +2341,7 @@ pub const DeclGen = struct {...@@ -2330,7 +2341,7 @@ pub const DeclGen = struct {
2330 return enum_tag_llvm_ty;2341 return enum_tag_llvm_ty;
2331 }2342 }
23322343
2333 const name = try union_obj.getFullyQualifiedName(gpa);2344 const name = try union_obj.getFullyQualifiedName(dg.module);
2334 defer gpa.free(name);2345 defer gpa.free(name);
23352346
2336 const llvm_union_ty = dg.context.structCreateNamed(name);2347 const llvm_union_ty = dg.context.structCreateNamed(name);
...@@ -2439,7 +2450,7 @@ pub const DeclGen = struct {...@@ -2439,7 +2450,7 @@ pub const DeclGen = struct {
2439 // TODO this duplicates code with Pointer but they should share the handling2450 // TODO this duplicates code with Pointer but they should share the handling
2440 // of the tv.val.tag() and then Int should do extra constPtrToInt on top2451 // of the tv.val.tag() and then Int should do extra constPtrToInt on top
2441 .Int => switch (tv.val.tag()) {2452 .Int => switch (tv.val.tag()) {
2442 .decl_ref_mut => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref_mut).?.data.decl),2453 .decl_ref_mut => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref_mut).?.data.decl_index),
2443 .decl_ref => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref).?.data),2454 .decl_ref => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref).?.data),
2444 else => {2455 else => {
2445 var bigint_space: Value.BigIntSpace = undefined;2456 var bigint_space: Value.BigIntSpace = undefined;
...@@ -2524,12 +2535,13 @@ pub const DeclGen = struct {...@@ -2524,12 +2535,13 @@ pub const DeclGen = struct {
2524 }2535 }
2525 },2536 },
2526 .Pointer => switch (tv.val.tag()) {2537 .Pointer => switch (tv.val.tag()) {
2527 .decl_ref_mut => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref_mut).?.data.decl),2538 .decl_ref_mut => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref_mut).?.data.decl_index),
2528 .decl_ref => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref).?.data),2539 .decl_ref => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref).?.data),
2529 .variable => {2540 .variable => {
2530 const decl = tv.val.castTag(.variable).?.data.owner_decl;2541 const decl_index = tv.val.castTag(.variable).?.data.owner_decl;
2531 decl.markAlive();2542 const decl = dg.module.declPtr(decl_index);
2532 const val = try dg.resolveGlobalDecl(decl);2543 dg.module.markDeclAlive(decl);
2544 const val = try dg.resolveGlobalDecl(decl_index);
2533 const llvm_var_type = try dg.llvmType(tv.ty);2545 const llvm_var_type = try dg.llvmType(tv.ty);
2534 const llvm_addrspace = dg.llvmAddressSpace(decl.@"addrspace");2546 const llvm_addrspace = dg.llvmAddressSpace(decl.@"addrspace");
2535 const llvm_type = llvm_var_type.pointerType(llvm_addrspace);2547 const llvm_type = llvm_var_type.pointerType(llvm_addrspace);
...@@ -2683,13 +2695,14 @@ pub const DeclGen = struct {...@@ -2683,13 +2695,14 @@ pub const DeclGen = struct {
2683 return dg.context.constStruct(&fields, fields.len, .False);2695 return dg.context.constStruct(&fields, fields.len, .False);
2684 },2696 },
2685 .Fn => {2697 .Fn => {
2686 const fn_decl = switch (tv.val.tag()) {2698 const fn_decl_index = switch (tv.val.tag()) {
2687 .extern_fn => tv.val.castTag(.extern_fn).?.data.owner_decl,2699 .extern_fn => tv.val.castTag(.extern_fn).?.data.owner_decl,
2688 .function => tv.val.castTag(.function).?.data.owner_decl,2700 .function => tv.val.castTag(.function).?.data.owner_decl,
2689 else => unreachable,2701 else => unreachable,
2690 };2702 };
2691 fn_decl.markAlive();2703 const fn_decl = dg.module.declPtr(fn_decl_index);
2692 return dg.resolveLlvmFunction(fn_decl);2704 dg.module.markDeclAlive(fn_decl);
2705 return dg.resolveLlvmFunction(fn_decl_index);
2693 },2706 },
2694 .ErrorSet => {2707 .ErrorSet => {
2695 const llvm_ty = try dg.llvmType(tv.ty);2708 const llvm_ty = try dg.llvmType(tv.ty);
...@@ -2911,7 +2924,7 @@ pub const DeclGen = struct {...@@ -2911,7 +2924,7 @@ pub const DeclGen = struct {
2911 });2924 });
2912 }2925 }
2913 const union_obj = tv.ty.cast(Type.Payload.Union).?.data;2926 const union_obj = tv.ty.cast(Type.Payload.Union).?.data;
2914 const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, target).?;2927 const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, dg.module).?;
2915 assert(union_obj.haveFieldTypes());2928 assert(union_obj.haveFieldTypes());
2916 const field_ty = union_obj.fields.values()[field_index].ty;2929 const field_ty = union_obj.fields.values()[field_index].ty;
2917 const payload = p: {2930 const payload = p: {
...@@ -3049,17 +3062,22 @@ pub const DeclGen = struct {...@@ -3049,17 +3062,22 @@ pub const DeclGen = struct {
3049 llvm_ptr: *const llvm.Value,3062 llvm_ptr: *const llvm.Value,
3050 };3063 };
30513064
3052 fn lowerParentPtrDecl(dg: *DeclGen, ptr_val: Value, decl: *Module.Decl, ptr_child_ty: Type) Error!*const llvm.Value {3065 fn lowerParentPtrDecl(
3053 decl.markAlive();3066 dg: *DeclGen,
3067 ptr_val: Value,
3068 decl_index: Module.Decl.Index,
3069 ptr_child_ty: Type,
3070 ) Error!*const llvm.Value {
3071 const decl = dg.module.declPtr(decl_index);
3072 dg.module.markDeclAlive(decl);
3054 var ptr_ty_payload: Type.Payload.ElemType = .{3073 var ptr_ty_payload: Type.Payload.ElemType = .{
3055 .base = .{ .tag = .single_mut_pointer },3074 .base = .{ .tag = .single_mut_pointer },
3056 .data = decl.ty,3075 .data = decl.ty,
3057 };3076 };
3058 const ptr_ty = Type.initPayload(&ptr_ty_payload.base);3077 const ptr_ty = Type.initPayload(&ptr_ty_payload.base);
3059 const llvm_ptr = try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl);3078 const llvm_ptr = try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index);
30603079
3061 const target = dg.module.getTarget();3080 if (ptr_child_ty.eql(decl.ty, dg.module)) {
3062 if (ptr_child_ty.eql(decl.ty, target)) {
3063 return llvm_ptr;3081 return llvm_ptr;
3064 } else {3082 } else {
3065 return llvm_ptr.constBitCast((try dg.llvmType(ptr_child_ty)).pointerType(0));3083 return llvm_ptr.constBitCast((try dg.llvmType(ptr_child_ty)).pointerType(0));
...@@ -3071,7 +3089,7 @@ pub const DeclGen = struct {...@@ -3071,7 +3089,7 @@ pub const DeclGen = struct {
3071 var bitcast_needed: bool = undefined;3089 var bitcast_needed: bool = undefined;
3072 const llvm_ptr = switch (ptr_val.tag()) {3090 const llvm_ptr = switch (ptr_val.tag()) {
3073 .decl_ref_mut => {3091 .decl_ref_mut => {
3074 const decl = ptr_val.castTag(.decl_ref_mut).?.data.decl;3092 const decl = ptr_val.castTag(.decl_ref_mut).?.data.decl_index;
3075 return dg.lowerParentPtrDecl(ptr_val, decl, ptr_child_ty);3093 return dg.lowerParentPtrDecl(ptr_val, decl, ptr_child_ty);
3076 },3094 },
3077 .decl_ref => {3095 .decl_ref => {
...@@ -3123,7 +3141,7 @@ pub const DeclGen = struct {...@@ -3123,7 +3141,7 @@ pub const DeclGen = struct {
3123 },3141 },
3124 .Struct => {3142 .Struct => {
3125 const field_ty = parent_ty.structFieldType(field_index);3143 const field_ty = parent_ty.structFieldType(field_index);
3126 bitcast_needed = !field_ty.eql(ptr_child_ty, target);3144 bitcast_needed = !field_ty.eql(ptr_child_ty, dg.module);
31273145
3128 var ty_buf: Type.Payload.Pointer = undefined;3146 var ty_buf: Type.Payload.Pointer = undefined;
3129 const llvm_field_index = llvmFieldIndex(parent_ty, field_index, target, &ty_buf).?;3147 const llvm_field_index = llvmFieldIndex(parent_ty, field_index, target, &ty_buf).?;
...@@ -3139,7 +3157,7 @@ pub const DeclGen = struct {...@@ -3139,7 +3157,7 @@ pub const DeclGen = struct {
3139 .elem_ptr => blk: {3157 .elem_ptr => blk: {
3140 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;3158 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
3141 const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr, elem_ptr.elem_ty);3159 const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr, elem_ptr.elem_ty);
3142 bitcast_needed = !elem_ptr.elem_ty.eql(ptr_child_ty, target);3160 bitcast_needed = !elem_ptr.elem_ty.eql(ptr_child_ty, dg.module);
31433161
3144 const llvm_usize = try dg.llvmType(Type.usize);3162 const llvm_usize = try dg.llvmType(Type.usize);
3145 const indices: [1]*const llvm.Value = .{3163 const indices: [1]*const llvm.Value = .{
...@@ -3153,7 +3171,7 @@ pub const DeclGen = struct {...@@ -3153,7 +3171,7 @@ pub const DeclGen = struct {
3153 var buf: Type.Payload.ElemType = undefined;3171 var buf: Type.Payload.ElemType = undefined;
31543172
3155 const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf);3173 const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf);
3156 bitcast_needed = !payload_ty.eql(ptr_child_ty, target);3174 bitcast_needed = !payload_ty.eql(ptr_child_ty, dg.module);
31573175
3158 if (!payload_ty.hasRuntimeBitsIgnoreComptime() or payload_ty.isPtrLikeOptional()) {3176 if (!payload_ty.hasRuntimeBitsIgnoreComptime() or payload_ty.isPtrLikeOptional()) {
3159 // In this case, we represent pointer to optional the same as pointer3177 // In this case, we represent pointer to optional the same as pointer
...@@ -3173,7 +3191,7 @@ pub const DeclGen = struct {...@@ -3173,7 +3191,7 @@ pub const DeclGen = struct {
3173 const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, eu_payload_ptr.container_ty);3191 const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, eu_payload_ptr.container_ty);
31743192
3175 const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload();3193 const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload();
3176 bitcast_needed = !payload_ty.eql(ptr_child_ty, target);3194 bitcast_needed = !payload_ty.eql(ptr_child_ty, dg.module);
31773195
3178 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {3196 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
3179 // In this case, we represent pointer to error union the same as pointer3197 // In this case, we represent pointer to error union the same as pointer
...@@ -3201,15 +3219,14 @@ pub const DeclGen = struct {...@@ -3201,15 +3219,14 @@ pub const DeclGen = struct {
3201 fn lowerDeclRefValue(3219 fn lowerDeclRefValue(
3202 self: *DeclGen,3220 self: *DeclGen,
3203 tv: TypedValue,3221 tv: TypedValue,
3204 decl: *Module.Decl,3222 decl_index: Module.Decl.Index,
3205 ) Error!*const llvm.Value {3223 ) Error!*const llvm.Value {
3206 const target = self.module.getTarget();
3207 if (tv.ty.isSlice()) {3224 if (tv.ty.isSlice()) {
3208 var buf: Type.SlicePtrFieldTypeBuffer = undefined;3225 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
3209 const ptr_ty = tv.ty.slicePtrFieldType(&buf);3226 const ptr_ty = tv.ty.slicePtrFieldType(&buf);
3210 var slice_len: Value.Payload.U64 = .{3227 var slice_len: Value.Payload.U64 = .{
3211 .base = .{ .tag = .int_u64 },3228 .base = .{ .tag = .int_u64 },
3212 .data = tv.val.sliceLen(target),3229 .data = tv.val.sliceLen(self.module),
3213 };3230 };
3214 const fields: [2]*const llvm.Value = .{3231 const fields: [2]*const llvm.Value = .{
3215 try self.genTypedValue(.{3232 try self.genTypedValue(.{
...@@ -3229,8 +3246,9 @@ pub const DeclGen = struct {...@@ -3229,8 +3246,9 @@ pub const DeclGen = struct {
3229 // const bar = foo;3246 // const bar = foo;
3230 // ... &bar;3247 // ... &bar;
3231 // `bar` is just an alias and we actually want to lower a reference to `foo`.3248 // `bar` is just an alias and we actually want to lower a reference to `foo`.
3249 const decl = self.module.declPtr(decl_index);
3232 if (decl.val.castTag(.function)) |func| {3250 if (decl.val.castTag(.function)) |func| {
3233 if (func.data.owner_decl != decl) {3251 if (func.data.owner_decl != decl_index) {
3234 return self.lowerDeclRefValue(tv, func.data.owner_decl);3252 return self.lowerDeclRefValue(tv, func.data.owner_decl);
3235 }3253 }
3236 }3254 }
...@@ -3240,12 +3258,12 @@ pub const DeclGen = struct {...@@ -3240,12 +3258,12 @@ pub const DeclGen = struct {
3240 return self.lowerPtrToVoid(tv.ty);3258 return self.lowerPtrToVoid(tv.ty);
3241 }3259 }
32423260
3243 decl.markAlive();3261 self.module.markDeclAlive(decl);
32443262
3245 const llvm_val = if (is_fn_body)3263 const llvm_val = if (is_fn_body)
3246 try self.resolveLlvmFunction(decl)3264 try self.resolveLlvmFunction(decl_index)
3247 else3265 else
3248 try self.resolveGlobalDecl(decl);3266 try self.resolveGlobalDecl(decl_index);
32493267
3250 const llvm_type = try self.llvmType(tv.ty);3268 const llvm_type = try self.llvmType(tv.ty);
3251 if (tv.ty.zigTypeTag() == .Int) {3269 if (tv.ty.zigTypeTag() == .Int) {
...@@ -4405,7 +4423,8 @@ pub const FuncGen = struct {...@@ -4405,7 +4423,8 @@ pub const FuncGen = struct {
4405 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;4423 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
44064424
4407 const func = self.air.values[ty_pl.payload].castTag(.function).?.data;4425 const func = self.air.values[ty_pl.payload].castTag(.function).?.data;
4408 const decl = func.owner_decl;4426 const decl_index = func.owner_decl;
4427 const decl = self.dg.module.declPtr(decl_index);
4409 const di_file = try self.dg.object.getDIFile(self.gpa, decl.src_namespace.file_scope);4428 const di_file = try self.dg.object.getDIFile(self.gpa, decl.src_namespace.file_scope);
4410 self.di_file = di_file;4429 self.di_file = di_file;
4411 const line_number = decl.src_line + 1;4430 const line_number = decl.src_line + 1;
...@@ -4417,10 +4436,10 @@ pub const FuncGen = struct {...@@ -4417,10 +4436,10 @@ pub const FuncGen = struct {
4417 .base_line = self.base_line,4436 .base_line = self.base_line,
4418 });4437 });
44194438
4420 const fqn = try decl.getFullyQualifiedName(self.gpa);4439 const fqn = try decl.getFullyQualifiedName(self.dg.module);
4421 defer self.gpa.free(fqn);4440 defer self.gpa.free(fqn);
44224441
4423 const is_internal_linkage = !self.dg.module.decl_exports.contains(decl);4442 const is_internal_linkage = !self.dg.module.decl_exports.contains(decl_index);
4424 const subprogram = dib.createFunction(4443 const subprogram = dib.createFunction(
4425 di_file.toScope(),4444 di_file.toScope(),
4426 decl.name,4445 decl.name,
...@@ -4447,7 +4466,8 @@ pub const FuncGen = struct {...@@ -4447,7 +4466,8 @@ pub const FuncGen = struct {
4447 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;4466 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
44484467
4449 const func = self.air.values[ty_pl.payload].castTag(.function).?.data;4468 const func = self.air.values[ty_pl.payload].castTag(.function).?.data;
4450 const decl = func.owner_decl;4469 const mod = self.dg.module;
4470 const decl = mod.declPtr(func.owner_decl);
4451 const di_file = try self.dg.object.getDIFile(self.gpa, decl.src_namespace.file_scope);4471 const di_file = try self.dg.object.getDIFile(self.gpa, decl.src_namespace.file_scope);
4452 self.di_file = di_file;4472 self.di_file = di_file;
4453 const old = self.dbg_inlined.pop();4473 const old = self.dbg_inlined.pop();
...@@ -5887,7 +5907,7 @@ pub const FuncGen = struct {...@@ -5887,7 +5907,7 @@ pub const FuncGen = struct {
5887 if (self.dg.object.di_builder) |dib| {5907 if (self.dg.object.di_builder) |dib| {
5888 const src_index = self.getSrcArgIndex(self.arg_index - 1);5908 const src_index = self.getSrcArgIndex(self.arg_index - 1);
5889 const func = self.dg.decl.getFunction().?;5909 const func = self.dg.decl.getFunction().?;
5890 const lbrace_line = func.owner_decl.src_line + func.lbrace_line + 1;5910 const lbrace_line = self.dg.module.declPtr(func.owner_decl).src_line + func.lbrace_line + 1;
5891 const lbrace_col = func.lbrace_column + 1;5911 const lbrace_col = func.lbrace_column + 1;
5892 const di_local_var = dib.createParameterVariable(5912 const di_local_var = dib.createParameterVariable(
5893 self.di_scope.?,5913 self.di_scope.?,
...@@ -6430,8 +6450,9 @@ pub const FuncGen = struct {...@@ -6430,8 +6450,9 @@ pub const FuncGen = struct {
6430 const operand = try self.resolveInst(un_op);6450 const operand = try self.resolveInst(un_op);
6431 const enum_ty = self.air.typeOf(un_op);6451 const enum_ty = self.air.typeOf(un_op);
64326452
6453 const mod = self.dg.module;
6433 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{6454 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{
6434 try enum_ty.getOwnerDecl().getFullyQualifiedName(arena),6455 try mod.declPtr(enum_ty.getOwnerDecl()).getFullyQualifiedName(mod),
6435 });6456 });
64366457
6437 const llvm_fn = try self.getEnumTagNameFunction(enum_ty, llvm_fn_name);6458 const llvm_fn = try self.getEnumTagNameFunction(enum_ty, llvm_fn_name);
...@@ -6617,7 +6638,7 @@ pub const FuncGen = struct {...@@ -6617,7 +6638,7 @@ pub const FuncGen = struct {
66176638
6618 for (values) |*val, i| {6639 for (values) |*val, i| {
6619 var buf: Value.ElemValueBuffer = undefined;6640 var buf: Value.ElemValueBuffer = undefined;
6620 const elem = mask.elemValueBuffer(i, &buf);6641 const elem = mask.elemValueBuffer(self.dg.module, i, &buf);
6621 if (elem.isUndef()) {6642 if (elem.isUndef()) {
6622 val.* = llvm_i32.getUndef();6643 val.* = llvm_i32.getUndef();
6623 } else {6644 } else {
src/codegen/spirv.zig+10-6
...@@ -633,7 +633,13 @@ pub const DeclGen = struct {...@@ -633,7 +633,13 @@ pub const DeclGen = struct {
633 return result_id.toRef();633 return result_id.toRef();
634 }634 }
635635
636 fn airArithOp(self: *DeclGen, inst: Air.Inst.Index, comptime fop: Opcode, comptime sop: Opcode, comptime uop: Opcode) !IdRef {636 fn airArithOp(
637 self: *DeclGen,
638 inst: Air.Inst.Index,
639 comptime fop: Opcode,
640 comptime sop: Opcode,
641 comptime uop: Opcode,
642 ) !IdRef {
637 // LHS and RHS are guaranteed to have the same type, and AIR guarantees643 // LHS and RHS are guaranteed to have the same type, and AIR guarantees
638 // the result to be the same as the LHS and RHS, which matches SPIR-V.644 // the result to be the same as the LHS and RHS, which matches SPIR-V.
639 const ty = self.air.typeOfIndex(inst);645 const ty = self.air.typeOfIndex(inst);
...@@ -644,10 +650,8 @@ pub const DeclGen = struct {...@@ -644,10 +650,8 @@ pub const DeclGen = struct {
644 const result_id = self.spv.allocId();650 const result_id = self.spv.allocId();
645 const result_type_id = try self.resolveTypeId(ty);651 const result_type_id = try self.resolveTypeId(ty);
646652
647 const target = self.getTarget();653 assert(self.air.typeOf(bin_op.lhs).eql(ty, self.module));
648654 assert(self.air.typeOf(bin_op.rhs).eql(ty, self.module));
649 assert(self.air.typeOf(bin_op.lhs).eql(ty, target));
650 assert(self.air.typeOf(bin_op.rhs).eql(ty, target));
651655
652 // Binary operations are generally applicable to both scalar and vector operations656 // Binary operations are generally applicable to both scalar and vector operations
653 // in SPIR-V, but int and float versions of operations require different opcodes.657 // in SPIR-V, but int and float versions of operations require different opcodes.
...@@ -694,7 +698,7 @@ pub const DeclGen = struct {...@@ -694,7 +698,7 @@ pub const DeclGen = struct {
694 const result_id = self.spv.allocId();698 const result_id = self.spv.allocId();
695 const result_type_id = try self.resolveTypeId(Type.initTag(.bool));699 const result_type_id = try self.resolveTypeId(Type.initTag(.bool));
696 const op_ty = self.air.typeOf(bin_op.lhs);700 const op_ty = self.air.typeOf(bin_op.lhs);
697 assert(op_ty.eql(self.air.typeOf(bin_op.rhs), self.getTarget()));701 assert(op_ty.eql(self.air.typeOf(bin_op.rhs), self.module));
698702
699 // Comparisons are generally applicable to both scalar and vector operations in SPIR-V,703 // Comparisons are generally applicable to both scalar and vector operations in SPIR-V,
700 // but int and float versions of operations require different opcodes.704 // but int and float versions of operations require different opcodes.
src/crash_report.zig+9-6
...@@ -90,9 +90,11 @@ fn dumpStatusReport() !void {...@@ -90,9 +90,11 @@ fn dumpStatusReport() !void {
9090
91 const stderr = io.getStdErr().writer();91 const stderr = io.getStdErr().writer();
92 const block: *Sema.Block = anal.block;92 const block: *Sema.Block = anal.block;
93 const mod = anal.sema.mod;
94 const block_src_decl = mod.declPtr(block.src_decl);
9395
94 try stderr.writeAll("Analyzing ");96 try stderr.writeAll("Analyzing ");
95 try writeFullyQualifiedDeclWithFile(block.src_decl, stderr);97 try writeFullyQualifiedDeclWithFile(mod, block_src_decl, stderr);
96 try stderr.writeAll("\n");98 try stderr.writeAll("\n");
9799
98 print_zir.renderInstructionContext(100 print_zir.renderInstructionContext(
...@@ -100,7 +102,7 @@ fn dumpStatusReport() !void {...@@ -100,7 +102,7 @@ fn dumpStatusReport() !void {
100 anal.body,102 anal.body,
101 anal.body_index,103 anal.body_index,
102 block.namespace.file_scope,104 block.namespace.file_scope,
103 block.src_decl.src_node,105 block_src_decl.src_node,
104 6, // indent106 6, // indent
105 stderr,107 stderr,
106 ) catch |err| switch (err) {108 ) catch |err| switch (err) {
...@@ -115,13 +117,14 @@ fn dumpStatusReport() !void {...@@ -115,13 +117,14 @@ fn dumpStatusReport() !void {
115 while (parent) |curr| {117 while (parent) |curr| {
116 fba.reset();118 fba.reset();
117 try stderr.writeAll(" in ");119 try stderr.writeAll(" in ");
118 try writeFullyQualifiedDeclWithFile(curr.block.src_decl, stderr);120 const curr_block_src_decl = mod.declPtr(curr.block.src_decl);
121 try writeFullyQualifiedDeclWithFile(mod, curr_block_src_decl, stderr);
119 try stderr.writeAll("\n > ");122 try stderr.writeAll("\n > ");
120 print_zir.renderSingleInstruction(123 print_zir.renderSingleInstruction(
121 allocator,124 allocator,
122 curr.body[curr.body_index],125 curr.body[curr.body_index],
123 curr.block.namespace.file_scope,126 curr.block.namespace.file_scope,
124 curr.block.src_decl.src_node,127 curr_block_src_decl.src_node,
125 6, // indent128 6, // indent
126 stderr,129 stderr,
127 ) catch |err| switch (err) {130 ) catch |err| switch (err) {
...@@ -146,10 +149,10 @@ fn writeFilePath(file: *Module.File, stream: anytype) !void {...@@ -146,10 +149,10 @@ fn writeFilePath(file: *Module.File, stream: anytype) !void {
146 try stream.writeAll(file.sub_file_path);149 try stream.writeAll(file.sub_file_path);
147}150}
148151
149fn writeFullyQualifiedDeclWithFile(decl: *Decl, stream: anytype) !void {152fn writeFullyQualifiedDeclWithFile(mod: *Module, decl: *Decl, stream: anytype) !void {
150 try writeFilePath(decl.getFileScope(), stream);153 try writeFilePath(decl.getFileScope(), stream);
151 try stream.writeAll(": ");154 try stream.writeAll(": ");
152 try decl.renderFullyQualifiedDebugName(stream);155 try decl.renderFullyQualifiedDebugName(mod, stream);
153}156}
154157
155pub fn compilerPanic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) noreturn {158pub fn compilerPanic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) noreturn {
src/link.zig+51-47
...@@ -417,17 +417,18 @@ pub const File = struct {...@@ -417,17 +417,18 @@ pub const File = struct {
417 /// Called from within the CodeGen to lower a local variable instantion as an unnamed417 /// Called from within the CodeGen to lower a local variable instantion as an unnamed
418 /// constant. Returns the symbol index of the lowered constant in the read-only section418 /// constant. Returns the symbol index of the lowered constant in the read-only section
419 /// of the final binary.419 /// of the final binary.
420 pub fn lowerUnnamedConst(base: *File, tv: TypedValue, decl: *Module.Decl) UpdateDeclError!u32 {420 pub fn lowerUnnamedConst(base: *File, tv: TypedValue, decl_index: Module.Decl.Index) UpdateDeclError!u32 {
421 const decl = base.options.module.?.declPtr(decl_index);
421 log.debug("lowerUnnamedConst {*} ({s})", .{ decl, decl.name });422 log.debug("lowerUnnamedConst {*} ({s})", .{ decl, decl.name });
422 switch (base.tag) {423 switch (base.tag) {
423 // zig fmt: off424 // zig fmt: off
424 .coff => return @fieldParentPtr(Coff, "base", base).lowerUnnamedConst(tv, decl),425 .coff => return @fieldParentPtr(Coff, "base", base).lowerUnnamedConst(tv, decl_index),
425 .elf => return @fieldParentPtr(Elf, "base", base).lowerUnnamedConst(tv, decl),426 .elf => return @fieldParentPtr(Elf, "base", base).lowerUnnamedConst(tv, decl_index),
426 .macho => return @fieldParentPtr(MachO, "base", base).lowerUnnamedConst(tv, decl),427 .macho => return @fieldParentPtr(MachO, "base", base).lowerUnnamedConst(tv, decl_index),
427 .plan9 => return @fieldParentPtr(Plan9, "base", base).lowerUnnamedConst(tv, decl),428 .plan9 => return @fieldParentPtr(Plan9, "base", base).lowerUnnamedConst(tv, decl_index),
428 .spirv => unreachable,429 .spirv => unreachable,
429 .c => unreachable,430 .c => unreachable,
430 .wasm => unreachable,431 .wasm => return @fieldParentPtr(Wasm, "base", base).lowerUnnamedConst(tv, decl_index),
431 .nvptx => unreachable,432 .nvptx => unreachable,
432 // zig fmt: on433 // zig fmt: on
433 }434 }
...@@ -435,19 +436,20 @@ pub const File = struct {...@@ -435,19 +436,20 @@ pub const File = struct {
435436
436 /// May be called before or after updateDeclExports but must be called437 /// May be called before or after updateDeclExports but must be called
437 /// after allocateDeclIndexes for any given Decl.438 /// after allocateDeclIndexes for any given Decl.
438 pub fn updateDecl(base: *File, module: *Module, decl: *Module.Decl) UpdateDeclError!void {439 pub fn updateDecl(base: *File, module: *Module, decl_index: Module.Decl.Index) UpdateDeclError!void {
440 const decl = module.declPtr(decl_index);
439 log.debug("updateDecl {*} ({s}), type={}", .{ decl, decl.name, decl.ty.fmtDebug() });441 log.debug("updateDecl {*} ({s}), type={}", .{ decl, decl.name, decl.ty.fmtDebug() });
440 assert(decl.has_tv);442 assert(decl.has_tv);
441 switch (base.tag) {443 switch (base.tag) {
442 // zig fmt: off444 // zig fmt: off
443 .coff => return @fieldParentPtr(Coff, "base", base).updateDecl(module, decl),445 .coff => return @fieldParentPtr(Coff, "base", base).updateDecl(module, decl_index),
444 .elf => return @fieldParentPtr(Elf, "base", base).updateDecl(module, decl),446 .elf => return @fieldParentPtr(Elf, "base", base).updateDecl(module, decl_index),
445 .macho => return @fieldParentPtr(MachO, "base", base).updateDecl(module, decl),447 .macho => return @fieldParentPtr(MachO, "base", base).updateDecl(module, decl_index),
446 .c => return @fieldParentPtr(C, "base", base).updateDecl(module, decl),448 .c => return @fieldParentPtr(C, "base", base).updateDecl(module, decl_index),
447 .wasm => return @fieldParentPtr(Wasm, "base", base).updateDecl(module, decl),449 .wasm => return @fieldParentPtr(Wasm, "base", base).updateDecl(module, decl_index),
448 .spirv => return @fieldParentPtr(SpirV, "base", base).updateDecl(module, decl),450 .spirv => return @fieldParentPtr(SpirV, "base", base).updateDecl(module, decl_index),
449 .plan9 => return @fieldParentPtr(Plan9, "base", base).updateDecl(module, decl),451 .plan9 => return @fieldParentPtr(Plan9, "base", base).updateDecl(module, decl_index),
450 .nvptx => return @fieldParentPtr(NvPtx, "base", base).updateDecl(module, decl),452 .nvptx => return @fieldParentPtr(NvPtx, "base", base).updateDecl(module, decl_index),
451 // zig fmt: on453 // zig fmt: on
452 }454 }
453 }455 }
...@@ -455,8 +457,9 @@ pub const File = struct {...@@ -455,8 +457,9 @@ pub const File = struct {
455 /// May be called before or after updateDeclExports but must be called457 /// May be called before or after updateDeclExports but must be called
456 /// after allocateDeclIndexes for any given Decl.458 /// after allocateDeclIndexes for any given Decl.
457 pub fn updateFunc(base: *File, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) UpdateDeclError!void {459 pub fn updateFunc(base: *File, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) UpdateDeclError!void {
460 const owner_decl = module.declPtr(func.owner_decl);
458 log.debug("updateFunc {*} ({s}), type={}", .{461 log.debug("updateFunc {*} ({s}), type={}", .{
459 func.owner_decl, func.owner_decl.name, func.owner_decl.ty.fmtDebug(),462 owner_decl, owner_decl.name, owner_decl.ty.fmtDebug(),
460 });463 });
461 switch (base.tag) {464 switch (base.tag) {
462 // zig fmt: off465 // zig fmt: off
...@@ -492,19 +495,20 @@ pub const File = struct {...@@ -492,19 +495,20 @@ pub const File = struct {
492 /// TODO we're transitioning to deleting this function and instead having495 /// TODO we're transitioning to deleting this function and instead having
493 /// each linker backend notice the first time updateDecl or updateFunc is called, or496 /// each linker backend notice the first time updateDecl or updateFunc is called, or
494 /// a callee referenced from AIR.497 /// a callee referenced from AIR.
495 pub fn allocateDeclIndexes(base: *File, decl: *Module.Decl) error{OutOfMemory}!void {498 pub fn allocateDeclIndexes(base: *File, decl_index: Module.Decl.Index) error{OutOfMemory}!void {
499 const decl = base.options.module.?.declPtr(decl_index);
496 log.debug("allocateDeclIndexes {*} ({s})", .{ decl, decl.name });500 log.debug("allocateDeclIndexes {*} ({s})", .{ decl, decl.name });
497 switch (base.tag) {501 switch (base.tag) {
498 .coff => return @fieldParentPtr(Coff, "base", base).allocateDeclIndexes(decl),502 .coff => return @fieldParentPtr(Coff, "base", base).allocateDeclIndexes(decl_index),
499 .elf => return @fieldParentPtr(Elf, "base", base).allocateDeclIndexes(decl),503 .elf => return @fieldParentPtr(Elf, "base", base).allocateDeclIndexes(decl_index),
500 .macho => return @fieldParentPtr(MachO, "base", base).allocateDeclIndexes(decl) catch |err| switch (err) {504 .macho => return @fieldParentPtr(MachO, "base", base).allocateDeclIndexes(decl_index) catch |err| switch (err) {
501 // remap this error code because we are transitioning away from505 // remap this error code because we are transitioning away from
502 // `allocateDeclIndexes`.506 // `allocateDeclIndexes`.
503 error.Overflow => return error.OutOfMemory,507 error.Overflow => return error.OutOfMemory,
504 error.OutOfMemory => return error.OutOfMemory,508 error.OutOfMemory => return error.OutOfMemory,
505 },509 },
506 .wasm => return @fieldParentPtr(Wasm, "base", base).allocateDeclIndexes(decl),510 .wasm => return @fieldParentPtr(Wasm, "base", base).allocateDeclIndexes(decl_index),
507 .plan9 => return @fieldParentPtr(Plan9, "base", base).allocateDeclIndexes(decl),511 .plan9 => return @fieldParentPtr(Plan9, "base", base).allocateDeclIndexes(decl_index),
508 .c, .spirv, .nvptx => {},512 .c, .spirv, .nvptx => {},
509 }513 }
510 }514 }
...@@ -621,17 +625,16 @@ pub const File = struct {...@@ -621,17 +625,16 @@ pub const File = struct {
621 }625 }
622626
623 /// Called when a Decl is deleted from the Module.627 /// Called when a Decl is deleted from the Module.
624 pub fn freeDecl(base: *File, decl: *Module.Decl) void {628 pub fn freeDecl(base: *File, decl_index: Module.Decl.Index) void {
625 log.debug("freeDecl {*} ({s})", .{ decl, decl.name });
626 switch (base.tag) {629 switch (base.tag) {
627 .coff => @fieldParentPtr(Coff, "base", base).freeDecl(decl),630 .coff => @fieldParentPtr(Coff, "base", base).freeDecl(decl_index),
628 .elf => @fieldParentPtr(Elf, "base", base).freeDecl(decl),631 .elf => @fieldParentPtr(Elf, "base", base).freeDecl(decl_index),
629 .macho => @fieldParentPtr(MachO, "base", base).freeDecl(decl),632 .macho => @fieldParentPtr(MachO, "base", base).freeDecl(decl_index),
630 .c => @fieldParentPtr(C, "base", base).freeDecl(decl),633 .c => @fieldParentPtr(C, "base", base).freeDecl(decl_index),
631 .wasm => @fieldParentPtr(Wasm, "base", base).freeDecl(decl),634 .wasm => @fieldParentPtr(Wasm, "base", base).freeDecl(decl_index),
632 .spirv => @fieldParentPtr(SpirV, "base", base).freeDecl(decl),635 .spirv => @fieldParentPtr(SpirV, "base", base).freeDecl(decl_index),
633 .plan9 => @fieldParentPtr(Plan9, "base", base).freeDecl(decl),636 .plan9 => @fieldParentPtr(Plan9, "base", base).freeDecl(decl_index),
634 .nvptx => @fieldParentPtr(NvPtx, "base", base).freeDecl(decl),637 .nvptx => @fieldParentPtr(NvPtx, "base", base).freeDecl(decl_index),
635 }638 }
636 }639 }
637640
...@@ -656,20 +659,21 @@ pub const File = struct {...@@ -656,20 +659,21 @@ pub const File = struct {
656 pub fn updateDeclExports(659 pub fn updateDeclExports(
657 base: *File,660 base: *File,
658 module: *Module,661 module: *Module,
659 decl: *Module.Decl,662 decl_index: Module.Decl.Index,
660 exports: []const *Module.Export,663 exports: []const *Module.Export,
661 ) UpdateDeclExportsError!void {664 ) UpdateDeclExportsError!void {
665 const decl = module.declPtr(decl_index);
662 log.debug("updateDeclExports {*} ({s})", .{ decl, decl.name });666 log.debug("updateDeclExports {*} ({s})", .{ decl, decl.name });
663 assert(decl.has_tv);667 assert(decl.has_tv);
664 switch (base.tag) {668 switch (base.tag) {
665 .coff => return @fieldParentPtr(Coff, "base", base).updateDeclExports(module, decl, exports),669 .coff => return @fieldParentPtr(Coff, "base", base).updateDeclExports(module, decl_index, exports),
666 .elf => return @fieldParentPtr(Elf, "base", base).updateDeclExports(module, decl, exports),670 .elf => return @fieldParentPtr(Elf, "base", base).updateDeclExports(module, decl_index, exports),
667 .macho => return @fieldParentPtr(MachO, "base", base).updateDeclExports(module, decl, exports),671 .macho => return @fieldParentPtr(MachO, "base", base).updateDeclExports(module, decl_index, exports),
668 .c => return @fieldParentPtr(C, "base", base).updateDeclExports(module, decl, exports),672 .c => return @fieldParentPtr(C, "base", base).updateDeclExports(module, decl_index, exports),
669 .wasm => return @fieldParentPtr(Wasm, "base", base).updateDeclExports(module, decl, exports),673 .wasm => return @fieldParentPtr(Wasm, "base", base).updateDeclExports(module, decl_index, exports),
670 .spirv => return @fieldParentPtr(SpirV, "base", base).updateDeclExports(module, decl, exports),674 .spirv => return @fieldParentPtr(SpirV, "base", base).updateDeclExports(module, decl_index, exports),
671 .plan9 => return @fieldParentPtr(Plan9, "base", base).updateDeclExports(module, decl, exports),675 .plan9 => return @fieldParentPtr(Plan9, "base", base).updateDeclExports(module, decl_index, exports),
672 .nvptx => return @fieldParentPtr(NvPtx, "base", base).updateDeclExports(module, decl, exports),676 .nvptx => return @fieldParentPtr(NvPtx, "base", base).updateDeclExports(module, decl_index, exports),
673 }677 }
674 }678 }
675679
...@@ -683,14 +687,14 @@ pub const File = struct {...@@ -683,14 +687,14 @@ pub const File = struct {
683 /// The linker is passed information about the containing atom, `parent_atom_index`, and offset within it's687 /// The linker is passed information about the containing atom, `parent_atom_index`, and offset within it's
684 /// memory buffer, `offset`, so that it can make a note of potential relocation sites, should the688 /// memory buffer, `offset`, so that it can make a note of potential relocation sites, should the
685 /// `Decl`'s address was not yet resolved, or the containing atom gets moved in virtual memory.689 /// `Decl`'s address was not yet resolved, or the containing atom gets moved in virtual memory.
686 pub fn getDeclVAddr(base: *File, decl: *const Module.Decl, reloc_info: RelocInfo) !u64 {690 pub fn getDeclVAddr(base: *File, decl_index: Module.Decl.Index, reloc_info: RelocInfo) !u64 {
687 switch (base.tag) {691 switch (base.tag) {
688 .coff => return @fieldParentPtr(Coff, "base", base).getDeclVAddr(decl, reloc_info),692 .coff => return @fieldParentPtr(Coff, "base", base).getDeclVAddr(decl_index, reloc_info),
689 .elf => return @fieldParentPtr(Elf, "base", base).getDeclVAddr(decl, reloc_info),693 .elf => return @fieldParentPtr(Elf, "base", base).getDeclVAddr(decl_index, reloc_info),
690 .macho => return @fieldParentPtr(MachO, "base", base).getDeclVAddr(decl, reloc_info),694 .macho => return @fieldParentPtr(MachO, "base", base).getDeclVAddr(decl_index, reloc_info),
691 .plan9 => return @fieldParentPtr(Plan9, "base", base).getDeclVAddr(decl, reloc_info),695 .plan9 => return @fieldParentPtr(Plan9, "base", base).getDeclVAddr(decl_index, reloc_info),
692 .c => unreachable,696 .c => unreachable,
693 .wasm => return @fieldParentPtr(Wasm, "base", base).getDeclVAddr(decl, reloc_info),697 .wasm => return @fieldParentPtr(Wasm, "base", base).getDeclVAddr(decl_index, reloc_info),
694 .spirv => unreachable,698 .spirv => unreachable,
695 .nvptx => unreachable,699 .nvptx => unreachable,
696 }700 }
src/link/C.zig+36-27
...@@ -21,7 +21,7 @@ base: link.File,...@@ -21,7 +21,7 @@ base: link.File,
21/// This linker backend does not try to incrementally link output C source code.21/// This linker backend does not try to incrementally link output C source code.
22/// Instead, it tracks all declarations in this table, and iterates over it22/// Instead, it tracks all declarations in this table, and iterates over it
23/// in the flush function, stitching pre-rendered pieces of C code together.23/// in the flush function, stitching pre-rendered pieces of C code together.
24decl_table: std.AutoArrayHashMapUnmanaged(*const Module.Decl, DeclBlock) = .{},24decl_table: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclBlock) = .{},
25/// Stores Type/Value data for `typedefs` to reference.25/// Stores Type/Value data for `typedefs` to reference.
26/// Accumulates allocations and then there is a periodic garbage collection after flush().26/// Accumulates allocations and then there is a periodic garbage collection after flush().
27arena: std.heap.ArenaAllocator,27arena: std.heap.ArenaAllocator,
...@@ -87,9 +87,9 @@ pub fn deinit(self: *C) void {...@@ -87,9 +87,9 @@ pub fn deinit(self: *C) void {
87 self.arena.deinit();87 self.arena.deinit();
88}88}
8989
90pub fn freeDecl(self: *C, decl: *Module.Decl) void {90pub fn freeDecl(self: *C, decl_index: Module.Decl.Index) void {
91 const gpa = self.base.allocator;91 const gpa = self.base.allocator;
92 if (self.decl_table.fetchSwapRemove(decl)) |kv| {92 if (self.decl_table.fetchSwapRemove(decl_index)) |kv| {
93 var decl_block = kv.value;93 var decl_block = kv.value;
94 decl_block.deinit(gpa);94 decl_block.deinit(gpa);
95 }95 }
...@@ -99,8 +99,8 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes...@@ -99,8 +99,8 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes
99 const tracy = trace(@src());99 const tracy = trace(@src());
100 defer tracy.end();100 defer tracy.end();
101101
102 const decl = func.owner_decl;102 const decl_index = func.owner_decl;
103 const gop = try self.decl_table.getOrPut(self.base.allocator, decl);103 const gop = try self.decl_table.getOrPut(self.base.allocator, decl_index);
104 if (!gop.found_existing) {104 if (!gop.found_existing) {
105 gop.value_ptr.* = .{};105 gop.value_ptr.* = .{};
106 }106 }
...@@ -126,9 +126,10 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes...@@ -126,9 +126,10 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes
126 .gpa = module.gpa,126 .gpa = module.gpa,
127 .module = module,127 .module = module,
128 .error_msg = null,128 .error_msg = null,
129 .decl = decl,129 .decl_index = decl_index,
130 .decl = module.declPtr(decl_index),
130 .fwd_decl = fwd_decl.toManaged(module.gpa),131 .fwd_decl = fwd_decl.toManaged(module.gpa),
131 .typedefs = typedefs.promoteContext(module.gpa, .{ .target = module.getTarget() }),132 .typedefs = typedefs.promoteContext(module.gpa, .{ .mod = module }),
132 .typedefs_arena = self.arena.allocator(),133 .typedefs_arena = self.arena.allocator(),
133 },134 },
134 .code = code.toManaged(module.gpa),135 .code = code.toManaged(module.gpa),
...@@ -150,7 +151,7 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes...@@ -150,7 +151,7 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes
150151
151 codegen.genFunc(&function) catch |err| switch (err) {152 codegen.genFunc(&function) catch |err| switch (err) {
152 error.AnalysisFail => {153 error.AnalysisFail => {
153 try module.failed_decls.put(module.gpa, decl, function.object.dg.error_msg.?);154 try module.failed_decls.put(module.gpa, decl_index, function.object.dg.error_msg.?);
154 return;155 return;
155 },156 },
156 else => |e| return e,157 else => |e| return e,
...@@ -166,11 +167,11 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes...@@ -166,11 +167,11 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes
166 code.shrinkAndFree(module.gpa, code.items.len);167 code.shrinkAndFree(module.gpa, code.items.len);
167}168}
168169
169pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void {170pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !void {
170 const tracy = trace(@src());171 const tracy = trace(@src());
171 defer tracy.end();172 defer tracy.end();
172173
173 const gop = try self.decl_table.getOrPut(self.base.allocator, decl);174 const gop = try self.decl_table.getOrPut(self.base.allocator, decl_index);
174 if (!gop.found_existing) {175 if (!gop.found_existing) {
175 gop.value_ptr.* = .{};176 gop.value_ptr.* = .{};
176 }177 }
...@@ -186,14 +187,17 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void {...@@ -186,14 +187,17 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void {
186 typedefs.clearRetainingCapacity();187 typedefs.clearRetainingCapacity();
187 code.shrinkRetainingCapacity(0);188 code.shrinkRetainingCapacity(0);
188189
190 const decl = module.declPtr(decl_index);
191
189 var object: codegen.Object = .{192 var object: codegen.Object = .{
190 .dg = .{193 .dg = .{
191 .gpa = module.gpa,194 .gpa = module.gpa,
192 .module = module,195 .module = module,
193 .error_msg = null,196 .error_msg = null,
197 .decl_index = decl_index,
194 .decl = decl,198 .decl = decl,
195 .fwd_decl = fwd_decl.toManaged(module.gpa),199 .fwd_decl = fwd_decl.toManaged(module.gpa),
196 .typedefs = typedefs.promoteContext(module.gpa, .{ .target = module.getTarget() }),200 .typedefs = typedefs.promoteContext(module.gpa, .{ .mod = module }),
197 .typedefs_arena = self.arena.allocator(),201 .typedefs_arena = self.arena.allocator(),
198 },202 },
199 .code = code.toManaged(module.gpa),203 .code = code.toManaged(module.gpa),
...@@ -211,7 +215,7 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void {...@@ -211,7 +215,7 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void {
211215
212 codegen.genDecl(&object) catch |err| switch (err) {216 codegen.genDecl(&object) catch |err| switch (err) {
213 error.AnalysisFail => {217 error.AnalysisFail => {
214 try module.failed_decls.put(module.gpa, decl, object.dg.error_msg.?);218 try module.failed_decls.put(module.gpa, decl_index, object.dg.error_msg.?);
215 return;219 return;
216 },220 },
217 else => |e| return e,221 else => |e| return e,
...@@ -287,14 +291,14 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)...@@ -287,14 +291,14 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)
287291
288 const decl_keys = self.decl_table.keys();292 const decl_keys = self.decl_table.keys();
289 const decl_values = self.decl_table.values();293 const decl_values = self.decl_table.values();
290 for (decl_keys) |decl| {294 for (decl_keys) |decl_index| {
291 assert(decl.has_tv);295 assert(module.declPtr(decl_index).has_tv);
292 f.remaining_decls.putAssumeCapacityNoClobber(decl, {});296 f.remaining_decls.putAssumeCapacityNoClobber(decl_index, {});
293 }297 }
294298
295 while (f.remaining_decls.popOrNull()) |kv| {299 while (f.remaining_decls.popOrNull()) |kv| {
296 const decl = kv.key;300 const decl_index = kv.key;
297 try flushDecl(self, &f, decl);301 try flushDecl(self, &f, decl_index);
298 }302 }
299303
300 f.all_buffers.items[err_typedef_index] = .{304 f.all_buffers.items[err_typedef_index] = .{
...@@ -305,7 +309,8 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)...@@ -305,7 +309,8 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)
305309
306 // Now the function bodies.310 // Now the function bodies.
307 try f.all_buffers.ensureUnusedCapacity(gpa, f.fn_count);311 try f.all_buffers.ensureUnusedCapacity(gpa, f.fn_count);
308 for (decl_keys) |decl, i| {312 for (decl_keys) |decl_index, i| {
313 const decl = module.declPtr(decl_index);
309 if (decl.getFunction() != null) {314 if (decl.getFunction() != null) {
310 const decl_block = &decl_values[i];315 const decl_block = &decl_values[i];
311 const buf = decl_block.code.items;316 const buf = decl_block.code.items;
...@@ -325,7 +330,7 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)...@@ -325,7 +330,7 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)
325}330}
326331
327const Flush = struct {332const Flush = struct {
328 remaining_decls: std.AutoArrayHashMapUnmanaged(*const Module.Decl, void) = .{},333 remaining_decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, void) = .{},
329 typedefs: Typedefs = .{},334 typedefs: Typedefs = .{},
330 err_typedef_buf: std.ArrayListUnmanaged(u8) = .{},335 err_typedef_buf: std.ArrayListUnmanaged(u8) = .{},
331 /// We collect a list of buffers to write, and write them all at once with pwritev 😎336 /// We collect a list of buffers to write, and write them all at once with pwritev 😎
...@@ -354,7 +359,9 @@ const FlushDeclError = error{...@@ -354,7 +359,9 @@ const FlushDeclError = error{
354};359};
355360
356/// Assumes `decl` was in the `remaining_decls` set, and has already been removed.361/// Assumes `decl` was in the `remaining_decls` set, and has already been removed.
357fn flushDecl(self: *C, f: *Flush, decl: *const Module.Decl) FlushDeclError!void {362fn flushDecl(self: *C, f: *Flush, decl_index: Module.Decl.Index) FlushDeclError!void {
363 const module = self.base.options.module.?;
364 const decl = module.declPtr(decl_index);
358 // Before flushing any particular Decl we must ensure its365 // Before flushing any particular Decl we must ensure its
359 // dependencies are already flushed, so that the order in the .c366 // dependencies are already flushed, so that the order in the .c
360 // file comes out correctly.367 // file comes out correctly.
...@@ -364,15 +371,17 @@ fn flushDecl(self: *C, f: *Flush, decl: *const Module.Decl) FlushDeclError!void...@@ -364,15 +371,17 @@ fn flushDecl(self: *C, f: *Flush, decl: *const Module.Decl) FlushDeclError!void
364 }371 }
365 }372 }
366373
367 const decl_block = self.decl_table.getPtr(decl).?;374 const decl_block = self.decl_table.getPtr(decl_index).?;
368 const gpa = self.base.allocator;375 const gpa = self.base.allocator;
369376
370 if (decl_block.typedefs.count() != 0) {377 if (decl_block.typedefs.count() != 0) {
371 try f.typedefs.ensureUnusedCapacity(gpa, @intCast(u32, decl_block.typedefs.count()));378 try f.typedefs.ensureUnusedCapacityContext(gpa, @intCast(u32, decl_block.typedefs.count()), .{
379 .mod = module,
380 });
372 var it = decl_block.typedefs.iterator();381 var it = decl_block.typedefs.iterator();
373 while (it.next()) |new| {382 while (it.next()) |new| {
374 const gop = f.typedefs.getOrPutAssumeCapacityContext(new.key_ptr.*, .{383 const gop = f.typedefs.getOrPutAssumeCapacityContext(new.key_ptr.*, .{
375 .target = self.base.options.target,384 .mod = module,
376 });385 });
377 if (!gop.found_existing) {386 if (!gop.found_existing) {
378 try f.err_typedef_buf.appendSlice(gpa, new.value_ptr.rendered);387 try f.err_typedef_buf.appendSlice(gpa, new.value_ptr.rendered);
...@@ -417,8 +426,8 @@ pub fn flushEmitH(module: *Module) !void {...@@ -417,8 +426,8 @@ pub fn flushEmitH(module: *Module) !void {
417 .iov_len = zig_h.len,426 .iov_len = zig_h.len,
418 });427 });
419428
420 for (emit_h.decl_table.keys()) |decl| {429 for (emit_h.decl_table.keys()) |decl_index| {
421 const decl_emit_h = decl.getEmitH(module);430 const decl_emit_h = emit_h.declPtr(decl_index);
422 const buf = decl_emit_h.fwd_decl.items;431 const buf = decl_emit_h.fwd_decl.items;
423 all_buffers.appendAssumeCapacity(.{432 all_buffers.appendAssumeCapacity(.{
424 .iov_base = buf.ptr,433 .iov_base = buf.ptr,
...@@ -442,11 +451,11 @@ pub fn flushEmitH(module: *Module) !void {...@@ -442,11 +451,11 @@ pub fn flushEmitH(module: *Module) !void {
442pub fn updateDeclExports(451pub fn updateDeclExports(
443 self: *C,452 self: *C,
444 module: *Module,453 module: *Module,
445 decl: *Module.Decl,454 decl_index: Module.Decl.Index,
446 exports: []const *Module.Export,455 exports: []const *Module.Export,
447) !void {456) !void {
448 _ = exports;457 _ = exports;
449 _ = decl;458 _ = decl_index;
450 _ = module;459 _ = module;
451 _ = self;460 _ = self;
452}461}
src/link/Coff.zig+32-17
...@@ -418,11 +418,12 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Coff {...@@ -418,11 +418,12 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Coff {
418 return self;418 return self;
419}419}
420420
421pub fn allocateDeclIndexes(self: *Coff, decl: *Module.Decl) !void {421pub fn allocateDeclIndexes(self: *Coff, decl_index: Module.Decl.Index) !void {
422 if (self.llvm_object) |_| return;422 if (self.llvm_object) |_| return;
423423
424 try self.offset_table.ensureUnusedCapacity(self.base.allocator, 1);424 try self.offset_table.ensureUnusedCapacity(self.base.allocator, 1);
425425
426 const decl = self.base.options.module.?.declPtr(decl_index);
426 if (self.offset_table_free_list.popOrNull()) |i| {427 if (self.offset_table_free_list.popOrNull()) |i| {
427 decl.link.coff.offset_table_index = i;428 decl.link.coff.offset_table_index = i;
428 } else {429 } else {
...@@ -674,7 +675,8 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live...@@ -674,7 +675,8 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live
674 var code_buffer = std.ArrayList(u8).init(self.base.allocator);675 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
675 defer code_buffer.deinit();676 defer code_buffer.deinit();
676677
677 const decl = func.owner_decl;678 const decl_index = func.owner_decl;
679 const decl = module.declPtr(decl_index);
678 const res = try codegen.generateFunction(680 const res = try codegen.generateFunction(
679 &self.base,681 &self.base,
680 decl.srcLoc(),682 decl.srcLoc(),
...@@ -688,7 +690,7 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live...@@ -688,7 +690,7 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live
688 .appended => code_buffer.items,690 .appended => code_buffer.items,
689 .fail => |em| {691 .fail => |em| {
690 decl.analysis = .codegen_failure;692 decl.analysis = .codegen_failure;
691 try module.failed_decls.put(module.gpa, decl, em);693 try module.failed_decls.put(module.gpa, decl_index, em);
692 return;694 return;
693 },695 },
694 };696 };
...@@ -696,24 +698,26 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live...@@ -696,24 +698,26 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live
696 return self.finishUpdateDecl(module, func.owner_decl, code);698 return self.finishUpdateDecl(module, func.owner_decl, code);
697}699}
698700
699pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl: *Module.Decl) !u32 {701pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.Index) !u32 {
700 _ = self;702 _ = self;
701 _ = tv;703 _ = tv;
702 _ = decl;704 _ = decl_index;
703 log.debug("TODO lowerUnnamedConst for Coff", .{});705 log.debug("TODO lowerUnnamedConst for Coff", .{});
704 return error.AnalysisFail;706 return error.AnalysisFail;
705}707}
706708
707pub fn updateDecl(self: *Coff, module: *Module, decl: *Module.Decl) !void {709pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) !void {
708 if (build_options.skip_non_native and builtin.object_format != .coff) {710 if (build_options.skip_non_native and builtin.object_format != .coff) {
709 @panic("Attempted to compile for object format that was disabled by build configuration");711 @panic("Attempted to compile for object format that was disabled by build configuration");
710 }712 }
711 if (build_options.have_llvm) {713 if (build_options.have_llvm) {
712 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(module, decl);714 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(module, decl_index);
713 }715 }
714 const tracy = trace(@src());716 const tracy = trace(@src());
715 defer tracy.end();717 defer tracy.end();
716718
719 const decl = module.declPtr(decl_index);
720
717 if (decl.val.tag() == .extern_fn) {721 if (decl.val.tag() == .extern_fn) {
718 return; // TODO Should we do more when front-end analyzed extern decl?722 return; // TODO Should we do more when front-end analyzed extern decl?
719 }723 }
...@@ -735,15 +739,16 @@ pub fn updateDecl(self: *Coff, module: *Module, decl: *Module.Decl) !void {...@@ -735,15 +739,16 @@ pub fn updateDecl(self: *Coff, module: *Module, decl: *Module.Decl) !void {
735 .appended => code_buffer.items,739 .appended => code_buffer.items,
736 .fail => |em| {740 .fail => |em| {
737 decl.analysis = .codegen_failure;741 decl.analysis = .codegen_failure;
738 try module.failed_decls.put(module.gpa, decl, em);742 try module.failed_decls.put(module.gpa, decl_index, em);
739 return;743 return;
740 },744 },
741 };745 };
742746
743 return self.finishUpdateDecl(module, decl, code);747 return self.finishUpdateDecl(module, decl_index, code);
744}748}
745749
746fn finishUpdateDecl(self: *Coff, module: *Module, decl: *Module.Decl, code: []const u8) !void {750fn finishUpdateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index, code: []const u8) !void {
751 const decl = module.declPtr(decl_index);
747 const required_alignment = decl.ty.abiAlignment(self.base.options.target);752 const required_alignment = decl.ty.abiAlignment(self.base.options.target);
748 const curr_size = decl.link.coff.size;753 const curr_size = decl.link.coff.size;
749 if (curr_size != 0) {754 if (curr_size != 0) {
...@@ -778,15 +783,18 @@ fn finishUpdateDecl(self: *Coff, module: *Module, decl: *Module.Decl, code: []co...@@ -778,15 +783,18 @@ fn finishUpdateDecl(self: *Coff, module: *Module, decl: *Module.Decl, code: []co
778 try self.base.file.?.pwriteAll(code, self.section_data_offset + self.offset_table_size + decl.link.coff.text_offset);783 try self.base.file.?.pwriteAll(code, self.section_data_offset + self.offset_table_size + decl.link.coff.text_offset);
779784
780 // Since we updated the vaddr and the size, each corresponding export symbol also needs to be updated.785 // Since we updated the vaddr and the size, each corresponding export symbol also needs to be updated.
781 const decl_exports = module.decl_exports.get(decl) orelse &[0]*Module.Export{};786 const decl_exports = module.decl_exports.get(decl_index) orelse &[0]*Module.Export{};
782 return self.updateDeclExports(module, decl, decl_exports);787 return self.updateDeclExports(module, decl_index, decl_exports);
783}788}
784789
785pub fn freeDecl(self: *Coff, decl: *Module.Decl) void {790pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void {
786 if (build_options.have_llvm) {791 if (build_options.have_llvm) {
787 if (self.llvm_object) |llvm_object| return llvm_object.freeDecl(decl);792 if (self.llvm_object) |llvm_object| return llvm_object.freeDecl(decl_index);
788 }793 }
789794
795 const mod = self.base.options.module.?;
796 const decl = mod.declPtr(decl_index);
797
790 // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.798 // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.
791 self.freeTextBlock(&decl.link.coff);799 self.freeTextBlock(&decl.link.coff);
792 self.offset_table_free_list.append(self.base.allocator, decl.link.coff.offset_table_index) catch {};800 self.offset_table_free_list.append(self.base.allocator, decl.link.coff.offset_table_index) catch {};
...@@ -795,16 +803,17 @@ pub fn freeDecl(self: *Coff, decl: *Module.Decl) void {...@@ -795,16 +803,17 @@ pub fn freeDecl(self: *Coff, decl: *Module.Decl) void {
795pub fn updateDeclExports(803pub fn updateDeclExports(
796 self: *Coff,804 self: *Coff,
797 module: *Module,805 module: *Module,
798 decl: *Module.Decl,806 decl_index: Module.Decl.Index,
799 exports: []const *Module.Export,807 exports: []const *Module.Export,
800) !void {808) !void {
801 if (build_options.skip_non_native and builtin.object_format != .coff) {809 if (build_options.skip_non_native and builtin.object_format != .coff) {
802 @panic("Attempted to compile for object format that was disabled by build configuration");810 @panic("Attempted to compile for object format that was disabled by build configuration");
803 }811 }
804 if (build_options.have_llvm) {812 if (build_options.have_llvm) {
805 if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(module, decl, exports);813 if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(module, decl_index, exports);
806 }814 }
807815
816 const decl = module.declPtr(decl_index);
808 for (exports) |exp| {817 for (exports) |exp| {
809 if (exp.options.section) |section_name| {818 if (exp.options.section) |section_name| {
810 if (!mem.eql(u8, section_name, ".text")) {819 if (!mem.eql(u8, section_name, ".text")) {
...@@ -1474,8 +1483,14 @@ fn findLib(self: *Coff, arena: Allocator, name: []const u8) !?[]const u8 {...@@ -1474,8 +1483,14 @@ fn findLib(self: *Coff, arena: Allocator, name: []const u8) !?[]const u8 {
1474 return null;1483 return null;
1475}1484}
14761485
1477pub fn getDeclVAddr(self: *Coff, decl: *const Module.Decl, reloc_info: link.File.RelocInfo) !u64 {1486pub fn getDeclVAddr(
1487 self: *Coff,
1488 decl_index: Module.Decl.Index,
1489 reloc_info: link.File.RelocInfo,
1490) !u64 {
1478 _ = reloc_info;1491 _ = reloc_info;
1492 const mod = self.base.options.module.?;
1493 const decl = mod.declPtr(decl_index);
1479 assert(self.llvm_object == null);1494 assert(self.llvm_object == null);
1480 return self.text_section_virtual_address + decl.link.coff.text_offset;1495 return self.text_section_virtual_address + decl.link.coff.text_offset;
1481}1496}
src/link/Dwarf.zig+23-23
...@@ -67,7 +67,7 @@ pub const Atom = struct {...@@ -67,7 +67,7 @@ pub const Atom = struct {
67/// Decl's inner Atom is assigned an offset within the DWARF section.67/// Decl's inner Atom is assigned an offset within the DWARF section.
68pub const DeclState = struct {68pub const DeclState = struct {
69 gpa: Allocator,69 gpa: Allocator,
70 target: std.Target,70 mod: *Module,
71 dbg_line: std.ArrayList(u8),71 dbg_line: std.ArrayList(u8),
72 dbg_info: std.ArrayList(u8),72 dbg_info: std.ArrayList(u8),
73 abbrev_type_arena: std.heap.ArenaAllocator,73 abbrev_type_arena: std.heap.ArenaAllocator,
...@@ -81,10 +81,10 @@ pub const DeclState = struct {...@@ -81,10 +81,10 @@ pub const DeclState = struct {
81 abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation) = .{},81 abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation) = .{},
82 exprloc_relocs: std.ArrayListUnmanaged(ExprlocRelocation) = .{},82 exprloc_relocs: std.ArrayListUnmanaged(ExprlocRelocation) = .{},
8383
84 fn init(gpa: Allocator, target: std.Target) DeclState {84 fn init(gpa: Allocator, mod: *Module) DeclState {
85 return .{85 return .{
86 .gpa = gpa,86 .gpa = gpa,
87 .target = target,87 .mod = mod,
88 .dbg_line = std.ArrayList(u8).init(gpa),88 .dbg_line = std.ArrayList(u8).init(gpa),
89 .dbg_info = std.ArrayList(u8).init(gpa),89 .dbg_info = std.ArrayList(u8).init(gpa),
90 .abbrev_type_arena = std.heap.ArenaAllocator.init(gpa),90 .abbrev_type_arena = std.heap.ArenaAllocator.init(gpa),
...@@ -118,7 +118,7 @@ pub const DeclState = struct {...@@ -118,7 +118,7 @@ pub const DeclState = struct {
118 addend: ?u32,118 addend: ?u32,
119 ) !void {119 ) !void {
120 const resolv = self.abbrev_resolver.getContext(ty, .{120 const resolv = self.abbrev_resolver.getContext(ty, .{
121 .target = self.target,121 .mod = self.mod,
122 }) orelse blk: {122 }) orelse blk: {
123 const sym_index = @intCast(u32, self.abbrev_table.items.len);123 const sym_index = @intCast(u32, self.abbrev_table.items.len);
124 try self.abbrev_table.append(self.gpa, .{124 try self.abbrev_table.append(self.gpa, .{
...@@ -128,10 +128,10 @@ pub const DeclState = struct {...@@ -128,10 +128,10 @@ pub const DeclState = struct {
128 });128 });
129 log.debug("@{d}: {}", .{ sym_index, ty.fmtDebug() });129 log.debug("@{d}: {}", .{ sym_index, ty.fmtDebug() });
130 try self.abbrev_resolver.putNoClobberContext(self.gpa, ty, sym_index, .{130 try self.abbrev_resolver.putNoClobberContext(self.gpa, ty, sym_index, .{
131 .target = self.target,131 .mod = self.mod,
132 });132 });
133 break :blk self.abbrev_resolver.getContext(ty, .{133 break :blk self.abbrev_resolver.getContext(ty, .{
134 .target = self.target,134 .mod = self.mod,
135 }).?;135 }).?;
136 };136 };
137 const add: u32 = addend orelse 0;137 const add: u32 = addend orelse 0;
...@@ -153,8 +153,8 @@ pub const DeclState = struct {...@@ -153,8 +153,8 @@ pub const DeclState = struct {
153 ) error{OutOfMemory}!void {153 ) error{OutOfMemory}!void {
154 const arena = self.abbrev_type_arena.allocator();154 const arena = self.abbrev_type_arena.allocator();
155 const dbg_info_buffer = &self.dbg_info;155 const dbg_info_buffer = &self.dbg_info;
156 const target = self.target;156 const target = module.getTarget();
157 const target_endian = self.target.cpu.arch.endian();157 const target_endian = target.cpu.arch.endian();
158158
159 switch (ty.zigTypeTag()) {159 switch (ty.zigTypeTag()) {
160 .NoReturn => unreachable,160 .NoReturn => unreachable,
...@@ -181,7 +181,7 @@ pub const DeclState = struct {...@@ -181,7 +181,7 @@ pub const DeclState = struct {
181 // DW.AT.byte_size, DW.FORM.data1181 // DW.AT.byte_size, DW.FORM.data1
182 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target)));182 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target)));
183 // DW.AT.name, DW.FORM.string183 // DW.AT.name, DW.FORM.string
184 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});184 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)});
185 },185 },
186 .Optional => {186 .Optional => {
187 if (ty.isPtrLikeOptional()) {187 if (ty.isPtrLikeOptional()) {
...@@ -192,7 +192,7 @@ pub const DeclState = struct {...@@ -192,7 +192,7 @@ pub const DeclState = struct {
192 // DW.AT.byte_size, DW.FORM.data1192 // DW.AT.byte_size, DW.FORM.data1
193 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target)));193 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target)));
194 // DW.AT.name, DW.FORM.string194 // DW.AT.name, DW.FORM.string
195 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});195 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)});
196 } else {196 } else {
197 // Non-pointer optionals are structs: struct { .maybe = *, .val = * }197 // Non-pointer optionals are structs: struct { .maybe = *, .val = * }
198 var buf = try arena.create(Type.Payload.ElemType);198 var buf = try arena.create(Type.Payload.ElemType);
...@@ -203,7 +203,7 @@ pub const DeclState = struct {...@@ -203,7 +203,7 @@ pub const DeclState = struct {
203 const abi_size = ty.abiSize(target);203 const abi_size = ty.abiSize(target);
204 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);204 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
205 // DW.AT.name, DW.FORM.string205 // DW.AT.name, DW.FORM.string
206 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});206 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)});
207 // DW.AT.member207 // DW.AT.member
208 try dbg_info_buffer.ensureUnusedCapacity(7);208 try dbg_info_buffer.ensureUnusedCapacity(7);
209 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));209 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
...@@ -242,7 +242,7 @@ pub const DeclState = struct {...@@ -242,7 +242,7 @@ pub const DeclState = struct {
242 // DW.AT.byte_size, DW.FORM.sdata242 // DW.AT.byte_size, DW.FORM.sdata
243 dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize) * 2);243 dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize) * 2);
244 // DW.AT.name, DW.FORM.string244 // DW.AT.name, DW.FORM.string
245 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});245 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)});
246 // DW.AT.member246 // DW.AT.member
247 try dbg_info_buffer.ensureUnusedCapacity(5);247 try dbg_info_buffer.ensureUnusedCapacity(5);
248 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));248 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
...@@ -285,7 +285,7 @@ pub const DeclState = struct {...@@ -285,7 +285,7 @@ pub const DeclState = struct {
285 // DW.AT.array_type285 // DW.AT.array_type
286 try dbg_info_buffer.append(@enumToInt(AbbrevKind.array_type));286 try dbg_info_buffer.append(@enumToInt(AbbrevKind.array_type));
287 // DW.AT.name, DW.FORM.string287 // DW.AT.name, DW.FORM.string
288 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});288 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)});
289 // DW.AT.type, DW.FORM.ref4289 // DW.AT.type, DW.FORM.ref4
290 var index = dbg_info_buffer.items.len;290 var index = dbg_info_buffer.items.len;
291 try dbg_info_buffer.resize(index + 4);291 try dbg_info_buffer.resize(index + 4);
...@@ -312,7 +312,7 @@ pub const DeclState = struct {...@@ -312,7 +312,7 @@ pub const DeclState = struct {
312 switch (ty.tag()) {312 switch (ty.tag()) {
313 .tuple, .anon_struct => {313 .tuple, .anon_struct => {
314 // DW.AT.name, DW.FORM.string314 // DW.AT.name, DW.FORM.string
315 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});315 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)});
316316
317 const fields = ty.tupleFields();317 const fields = ty.tupleFields();
318 for (fields.types) |field, field_index| {318 for (fields.types) |field, field_index| {
...@@ -331,7 +331,7 @@ pub const DeclState = struct {...@@ -331,7 +331,7 @@ pub const DeclState = struct {
331 },331 },
332 else => {332 else => {
333 // DW.AT.name, DW.FORM.string333 // DW.AT.name, DW.FORM.string
334 const struct_name = try ty.nameAllocArena(arena, target);334 const struct_name = try ty.nameAllocArena(arena, module);
335 try dbg_info_buffer.ensureUnusedCapacity(struct_name.len + 1);335 try dbg_info_buffer.ensureUnusedCapacity(struct_name.len + 1);
336 dbg_info_buffer.appendSliceAssumeCapacity(struct_name);336 dbg_info_buffer.appendSliceAssumeCapacity(struct_name);
337 dbg_info_buffer.appendAssumeCapacity(0);337 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -372,7 +372,7 @@ pub const DeclState = struct {...@@ -372,7 +372,7 @@ pub const DeclState = struct {
372 const abi_size = ty.abiSize(target);372 const abi_size = ty.abiSize(target);
373 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);373 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
374 // DW.AT.name, DW.FORM.string374 // DW.AT.name, DW.FORM.string
375 const enum_name = try ty.nameAllocArena(arena, target);375 const enum_name = try ty.nameAllocArena(arena, module);
376 try dbg_info_buffer.ensureUnusedCapacity(enum_name.len + 1);376 try dbg_info_buffer.ensureUnusedCapacity(enum_name.len + 1);
377 dbg_info_buffer.appendSliceAssumeCapacity(enum_name);377 dbg_info_buffer.appendSliceAssumeCapacity(enum_name);
378 dbg_info_buffer.appendAssumeCapacity(0);378 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -410,7 +410,7 @@ pub const DeclState = struct {...@@ -410,7 +410,7 @@ pub const DeclState = struct {
410 const payload_offset = if (layout.tag_align >= layout.payload_align) layout.tag_size else 0;410 const payload_offset = if (layout.tag_align >= layout.payload_align) layout.tag_size else 0;
411 const tag_offset = if (layout.tag_align >= layout.payload_align) 0 else layout.payload_size;411 const tag_offset = if (layout.tag_align >= layout.payload_align) 0 else layout.payload_size;
412 const is_tagged = layout.tag_size > 0;412 const is_tagged = layout.tag_size > 0;
413 const union_name = try ty.nameAllocArena(arena, target);413 const union_name = try ty.nameAllocArena(arena, module);
414414
415 // TODO this is temporary to match current state of unions in Zig - we don't yet have415 // TODO this is temporary to match current state of unions in Zig - we don't yet have
416 // safety checks implemented meaning the implicit tag is not yet stored and generated416 // safety checks implemented meaning the implicit tag is not yet stored and generated
...@@ -491,7 +491,7 @@ pub const DeclState = struct {...@@ -491,7 +491,7 @@ pub const DeclState = struct {
491 self.abbrev_type_arena.allocator(),491 self.abbrev_type_arena.allocator(),
492 module,492 module,
493 ty,493 ty,
494 self.target,494 target,
495 &self.dbg_info,495 &self.dbg_info,
496 );496 );
497 },497 },
...@@ -507,7 +507,7 @@ pub const DeclState = struct {...@@ -507,7 +507,7 @@ pub const DeclState = struct {
507 // DW.AT.byte_size, DW.FORM.sdata507 // DW.AT.byte_size, DW.FORM.sdata
508 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);508 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
509 // DW.AT.name, DW.FORM.string509 // DW.AT.name, DW.FORM.string
510 const name = try ty.nameAllocArena(arena, target);510 const name = try ty.nameAllocArena(arena, module);
511 try dbg_info_buffer.writer().print("{s}\x00", .{name});511 try dbg_info_buffer.writer().print("{s}\x00", .{name});
512512
513 // DW.AT.member513 // DW.AT.member
...@@ -654,17 +654,17 @@ pub fn deinit(self: *Dwarf) void {...@@ -654,17 +654,17 @@ pub fn deinit(self: *Dwarf) void {
654654
655/// Initializes Decl's state and its matching output buffers.655/// Initializes Decl's state and its matching output buffers.
656/// Call this before `commitDeclState`.656/// Call this before `commitDeclState`.
657pub fn initDeclState(self: *Dwarf, decl: *Module.Decl) !DeclState {657pub fn initDeclState(self: *Dwarf, mod: *Module, decl: *Module.Decl) !DeclState {
658 const tracy = trace(@src());658 const tracy = trace(@src());
659 defer tracy.end();659 defer tracy.end();
660660
661 const decl_name = try decl.getFullyQualifiedName(self.allocator);661 const decl_name = try decl.getFullyQualifiedName(mod);
662 defer self.allocator.free(decl_name);662 defer self.allocator.free(decl_name);
663663
664 log.debug("initDeclState {s}{*}", .{ decl_name, decl });664 log.debug("initDeclState {s}{*}", .{ decl_name, decl });
665665
666 const gpa = self.allocator;666 const gpa = self.allocator;
667 var decl_state = DeclState.init(gpa, self.target);667 var decl_state = DeclState.init(gpa, mod);
668 errdefer decl_state.deinit();668 errdefer decl_state.deinit();
669 const dbg_line_buffer = &decl_state.dbg_line;669 const dbg_line_buffer = &decl_state.dbg_line;
670 const dbg_info_buffer = &decl_state.dbg_info;670 const dbg_info_buffer = &decl_state.dbg_info;
...@@ -2133,7 +2133,7 @@ fn addDbgInfoErrorSet(...@@ -2133,7 +2133,7 @@ fn addDbgInfoErrorSet(
2133 const abi_size = ty.abiSize(target);2133 const abi_size = ty.abiSize(target);
2134 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);2134 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
2135 // DW.AT.name, DW.FORM.string2135 // DW.AT.name, DW.FORM.string
2136 const name = try ty.nameAllocArena(arena, target);2136 const name = try ty.nameAllocArena(arena, module);
2137 try dbg_info_buffer.writer().print("{s}\x00", .{name});2137 try dbg_info_buffer.writer().print("{s}\x00", .{name});
21382138
2139 // DW.AT.enumerator2139 // DW.AT.enumerator
src/link/Elf.zig+57-41
...@@ -134,7 +134,7 @@ atom_free_lists: std.AutoHashMapUnmanaged(u16, std.ArrayListUnmanaged(*TextBlock...@@ -134,7 +134,7 @@ atom_free_lists: std.AutoHashMapUnmanaged(u16, std.ArrayListUnmanaged(*TextBlock
134/// We store them here so that we can properly dispose of any allocated134/// We store them here so that we can properly dispose of any allocated
135/// memory within the atom in the incremental linker.135/// memory within the atom in the incremental linker.
136/// TODO consolidate this.136/// TODO consolidate this.
137decls: std.AutoHashMapUnmanaged(*Module.Decl, ?u16) = .{},137decls: std.AutoHashMapUnmanaged(Module.Decl.Index, ?u16) = .{},
138138
139/// List of atoms that are owned directly by the linker.139/// List of atoms that are owned directly by the linker.
140/// Currently these are only atoms that are the result of linking140/// Currently these are only atoms that are the result of linking
...@@ -178,7 +178,7 @@ const Reloc = struct {...@@ -178,7 +178,7 @@ const Reloc = struct {
178};178};
179179
180const RelocTable = std.AutoHashMapUnmanaged(*TextBlock, std.ArrayListUnmanaged(Reloc));180const RelocTable = std.AutoHashMapUnmanaged(*TextBlock, std.ArrayListUnmanaged(Reloc));
181const UnnamedConstTable = std.AutoHashMapUnmanaged(*Module.Decl, std.ArrayListUnmanaged(*TextBlock));181const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(*TextBlock));
182182
183/// When allocating, the ideal_capacity is calculated by183/// When allocating, the ideal_capacity is calculated by
184/// actual_capacity + (actual_capacity / ideal_factor)184/// actual_capacity + (actual_capacity / ideal_factor)
...@@ -389,7 +389,10 @@ pub fn deinit(self: *Elf) void {...@@ -389,7 +389,10 @@ pub fn deinit(self: *Elf) void {
389 }389 }
390}390}
391391
392pub fn getDeclVAddr(self: *Elf, decl: *const Module.Decl, reloc_info: File.RelocInfo) !u64 {392pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: File.RelocInfo) !u64 {
393 const mod = self.base.options.module.?;
394 const decl = mod.declPtr(decl_index);
395
393 assert(self.llvm_object == null);396 assert(self.llvm_object == null);
394 assert(decl.link.elf.local_sym_index != 0);397 assert(decl.link.elf.local_sym_index != 0);
395398
...@@ -2189,15 +2192,17 @@ fn allocateLocalSymbol(self: *Elf) !u32 {...@@ -2189,15 +2192,17 @@ fn allocateLocalSymbol(self: *Elf) !u32 {
2189 return index;2192 return index;
2190}2193}
21912194
2192pub fn allocateDeclIndexes(self: *Elf, decl: *Module.Decl) !void {2195pub fn allocateDeclIndexes(self: *Elf, decl_index: Module.Decl.Index) !void {
2193 if (self.llvm_object) |_| return;2196 if (self.llvm_object) |_| return;
21942197
2198 const mod = self.base.options.module.?;
2199 const decl = mod.declPtr(decl_index);
2195 if (decl.link.elf.local_sym_index != 0) return;2200 if (decl.link.elf.local_sym_index != 0) return;
21962201
2197 try self.offset_table.ensureUnusedCapacity(self.base.allocator, 1);2202 try self.offset_table.ensureUnusedCapacity(self.base.allocator, 1);
2198 try self.decls.putNoClobber(self.base.allocator, decl, null);2203 try self.decls.putNoClobber(self.base.allocator, decl_index, null);
21992204
2200 const decl_name = try decl.getFullyQualifiedName(self.base.allocator);2205 const decl_name = try decl.getFullyQualifiedName(mod);
2201 defer self.base.allocator.free(decl_name);2206 defer self.base.allocator.free(decl_name);
22022207
2203 log.debug("allocating symbol indexes for {s}", .{decl_name});2208 log.debug("allocating symbol indexes for {s}", .{decl_name});
...@@ -2214,8 +2219,8 @@ pub fn allocateDeclIndexes(self: *Elf, decl: *Module.Decl) !void {...@@ -2214,8 +2219,8 @@ pub fn allocateDeclIndexes(self: *Elf, decl: *Module.Decl) !void {
2214 self.offset_table.items[decl.link.elf.offset_table_index] = 0;2219 self.offset_table.items[decl.link.elf.offset_table_index] = 0;
2215}2220}
22162221
2217fn freeUnnamedConsts(self: *Elf, decl: *Module.Decl) void {2222fn freeUnnamedConsts(self: *Elf, decl_index: Module.Decl.Index) void {
2218 const unnamed_consts = self.unnamed_const_atoms.getPtr(decl) orelse return;2223 const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return;
2219 for (unnamed_consts.items) |atom| {2224 for (unnamed_consts.items) |atom| {
2220 self.freeTextBlock(atom, self.phdr_load_ro_index.?);2225 self.freeTextBlock(atom, self.phdr_load_ro_index.?);
2221 self.local_symbol_free_list.append(self.base.allocator, atom.local_sym_index) catch {};2226 self.local_symbol_free_list.append(self.base.allocator, atom.local_sym_index) catch {};
...@@ -2225,15 +2230,18 @@ fn freeUnnamedConsts(self: *Elf, decl: *Module.Decl) void {...@@ -2225,15 +2230,18 @@ fn freeUnnamedConsts(self: *Elf, decl: *Module.Decl) void {
2225 unnamed_consts.clearAndFree(self.base.allocator);2230 unnamed_consts.clearAndFree(self.base.allocator);
2226}2231}
22272232
2228pub fn freeDecl(self: *Elf, decl: *Module.Decl) void {2233pub fn freeDecl(self: *Elf, decl_index: Module.Decl.Index) void {
2229 if (build_options.have_llvm) {2234 if (build_options.have_llvm) {
2230 if (self.llvm_object) |llvm_object| return llvm_object.freeDecl(decl);2235 if (self.llvm_object) |llvm_object| return llvm_object.freeDecl(decl_index);
2231 }2236 }
22322237
2233 const kv = self.decls.fetchRemove(decl);2238 const mod = self.base.options.module.?;
2239 const decl = mod.declPtr(decl_index);
2240
2241 const kv = self.decls.fetchRemove(decl_index);
2234 if (kv.?.value) |index| {2242 if (kv.?.value) |index| {
2235 self.freeTextBlock(&decl.link.elf, index);2243 self.freeTextBlock(&decl.link.elf, index);
2236 self.freeUnnamedConsts(decl);2244 self.freeUnnamedConsts(decl_index);
2237 }2245 }
22382246
2239 // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.2247 // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.
...@@ -2274,14 +2282,17 @@ fn getDeclPhdrIndex(self: *Elf, decl: *Module.Decl) !u16 {...@@ -2274,14 +2282,17 @@ fn getDeclPhdrIndex(self: *Elf, decl: *Module.Decl) !u16 {
2274 return phdr_index;2282 return phdr_index;
2275}2283}
22762284
2277fn updateDeclCode(self: *Elf, decl: *Module.Decl, code: []const u8, stt_bits: u8) !*elf.Elf64_Sym {2285fn updateDeclCode(self: *Elf, decl_index: Module.Decl.Index, code: []const u8, stt_bits: u8) !*elf.Elf64_Sym {
2278 const decl_name = try decl.getFullyQualifiedName(self.base.allocator);2286 const mod = self.base.options.module.?;
2287 const decl = mod.declPtr(decl_index);
2288
2289 const decl_name = try decl.getFullyQualifiedName(mod);
2279 defer self.base.allocator.free(decl_name);2290 defer self.base.allocator.free(decl_name);
22802291
2281 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });2292 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });
2282 const required_alignment = decl.ty.abiAlignment(self.base.options.target);2293 const required_alignment = decl.ty.abiAlignment(self.base.options.target);
22832294
2284 const decl_ptr = self.decls.getPtr(decl).?;2295 const decl_ptr = self.decls.getPtr(decl_index).?;
2285 if (decl_ptr.* == null) {2296 if (decl_ptr.* == null) {
2286 decl_ptr.* = try self.getDeclPhdrIndex(decl);2297 decl_ptr.* = try self.getDeclPhdrIndex(decl);
2287 }2298 }
...@@ -2355,10 +2366,11 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven...@@ -2355,10 +2366,11 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
2355 var code_buffer = std.ArrayList(u8).init(self.base.allocator);2366 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
2356 defer code_buffer.deinit();2367 defer code_buffer.deinit();
23572368
2358 const decl = func.owner_decl;2369 const decl_index = func.owner_decl;
2359 self.freeUnnamedConsts(decl);2370 const decl = module.declPtr(decl_index);
2371 self.freeUnnamedConsts(decl_index);
23602372
2361 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(decl) else null;2373 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(module, decl) else null;
2362 defer if (decl_state) |*ds| ds.deinit();2374 defer if (decl_state) |*ds| ds.deinit();
23632375
2364 const res = if (decl_state) |*ds|2376 const res = if (decl_state) |*ds|
...@@ -2372,11 +2384,11 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven...@@ -2372,11 +2384,11 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
2372 .appended => code_buffer.items,2384 .appended => code_buffer.items,
2373 .fail => |em| {2385 .fail => |em| {
2374 decl.analysis = .codegen_failure;2386 decl.analysis = .codegen_failure;
2375 try module.failed_decls.put(module.gpa, decl, em);2387 try module.failed_decls.put(module.gpa, decl_index, em);
2376 return;2388 return;
2377 },2389 },
2378 };2390 };
2379 const local_sym = try self.updateDeclCode(decl, code, elf.STT_FUNC);2391 const local_sym = try self.updateDeclCode(decl_index, code, elf.STT_FUNC);
2380 if (decl_state) |*ds| {2392 if (decl_state) |*ds| {
2381 try self.dwarf.?.commitDeclState(2393 try self.dwarf.?.commitDeclState(
2382 &self.base,2394 &self.base,
...@@ -2389,21 +2401,23 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven...@@ -2389,21 +2401,23 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
2389 }2401 }
23902402
2391 // Since we updated the vaddr and the size, each corresponding export symbol also needs to be updated.2403 // Since we updated the vaddr and the size, each corresponding export symbol also needs to be updated.
2392 const decl_exports = module.decl_exports.get(decl) orelse &[0]*Module.Export{};2404 const decl_exports = module.decl_exports.get(decl_index) orelse &[0]*Module.Export{};
2393 return self.updateDeclExports(module, decl, decl_exports);2405 return self.updateDeclExports(module, decl_index, decl_exports);
2394}2406}
23952407
2396pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {2408pub fn updateDecl(self: *Elf, module: *Module, decl_index: Module.Decl.Index) !void {
2397 if (build_options.skip_non_native and builtin.object_format != .elf) {2409 if (build_options.skip_non_native and builtin.object_format != .elf) {
2398 @panic("Attempted to compile for object format that was disabled by build configuration");2410 @panic("Attempted to compile for object format that was disabled by build configuration");
2399 }2411 }
2400 if (build_options.have_llvm) {2412 if (build_options.have_llvm) {
2401 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(module, decl);2413 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(module, decl_index);
2402 }2414 }
24032415
2404 const tracy = trace(@src());2416 const tracy = trace(@src());
2405 defer tracy.end();2417 defer tracy.end();
24062418
2419 const decl = module.declPtr(decl_index);
2420
2407 if (decl.val.tag() == .extern_fn) {2421 if (decl.val.tag() == .extern_fn) {
2408 return; // TODO Should we do more when front-end analyzed extern decl?2422 return; // TODO Should we do more when front-end analyzed extern decl?
2409 }2423 }
...@@ -2414,12 +2428,12 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {...@@ -2414,12 +2428,12 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
2414 }2428 }
2415 }2429 }
24162430
2417 assert(!self.unnamed_const_atoms.contains(decl));2431 assert(!self.unnamed_const_atoms.contains(decl_index));
24182432
2419 var code_buffer = std.ArrayList(u8).init(self.base.allocator);2433 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
2420 defer code_buffer.deinit();2434 defer code_buffer.deinit();
24212435
2422 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(decl) else null;2436 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(module, decl) else null;
2423 defer if (decl_state) |*ds| ds.deinit();2437 defer if (decl_state) |*ds| ds.deinit();
24242438
2425 // TODO implement .debug_info for global variables2439 // TODO implement .debug_info for global variables
...@@ -2446,12 +2460,12 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {...@@ -2446,12 +2460,12 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
2446 .appended => code_buffer.items,2460 .appended => code_buffer.items,
2447 .fail => |em| {2461 .fail => |em| {
2448 decl.analysis = .codegen_failure;2462 decl.analysis = .codegen_failure;
2449 try module.failed_decls.put(module.gpa, decl, em);2463 try module.failed_decls.put(module.gpa, decl_index, em);
2450 return;2464 return;
2451 },2465 },
2452 };2466 };
24532467
2454 const local_sym = try self.updateDeclCode(decl, code, elf.STT_OBJECT);2468 const local_sym = try self.updateDeclCode(decl_index, code, elf.STT_OBJECT);
2455 if (decl_state) |*ds| {2469 if (decl_state) |*ds| {
2456 try self.dwarf.?.commitDeclState(2470 try self.dwarf.?.commitDeclState(
2457 &self.base,2471 &self.base,
...@@ -2464,16 +2478,18 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {...@@ -2464,16 +2478,18 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
2464 }2478 }
24652479
2466 // Since we updated the vaddr and the size, each corresponding export symbol also needs to be updated.2480 // Since we updated the vaddr and the size, each corresponding export symbol also needs to be updated.
2467 const decl_exports = module.decl_exports.get(decl) orelse &[0]*Module.Export{};2481 const decl_exports = module.decl_exports.get(decl_index) orelse &[0]*Module.Export{};
2468 return self.updateDeclExports(module, decl, decl_exports);2482 return self.updateDeclExports(module, decl_index, decl_exports);
2469}2483}
24702484
2471pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl: *Module.Decl) !u32 {2485pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module.Decl.Index) !u32 {
2472 var code_buffer = std.ArrayList(u8).init(self.base.allocator);2486 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
2473 defer code_buffer.deinit();2487 defer code_buffer.deinit();
24742488
2475 const module = self.base.options.module.?;2489 const mod = self.base.options.module.?;
2476 const gop = try self.unnamed_const_atoms.getOrPut(self.base.allocator, decl);2490 const decl = mod.declPtr(decl_index);
2491
2492 const gop = try self.unnamed_const_atoms.getOrPut(self.base.allocator, decl_index);
2477 if (!gop.found_existing) {2493 if (!gop.found_existing) {
2478 gop.value_ptr.* = .{};2494 gop.value_ptr.* = .{};
2479 }2495 }
...@@ -2485,7 +2501,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl: *Module.Decl...@@ -2485,7 +2501,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl: *Module.Decl
2485 try self.managed_atoms.append(self.base.allocator, atom);2501 try self.managed_atoms.append(self.base.allocator, atom);
24862502
2487 const name_str_index = blk: {2503 const name_str_index = blk: {
2488 const decl_name = try decl.getFullyQualifiedName(self.base.allocator);2504 const decl_name = try decl.getFullyQualifiedName(mod);
2489 defer self.base.allocator.free(decl_name);2505 defer self.base.allocator.free(decl_name);
24902506
2491 const index = unnamed_consts.items.len;2507 const index = unnamed_consts.items.len;
...@@ -2510,7 +2526,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl: *Module.Decl...@@ -2510,7 +2526,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl: *Module.Decl
2510 .appended => code_buffer.items,2526 .appended => code_buffer.items,
2511 .fail => |em| {2527 .fail => |em| {
2512 decl.analysis = .codegen_failure;2528 decl.analysis = .codegen_failure;
2513 try module.failed_decls.put(module.gpa, decl, em);2529 try mod.failed_decls.put(mod.gpa, decl_index, em);
2514 log.err("{s}", .{em.msg});2530 log.err("{s}", .{em.msg});
2515 return error.AnalysisFail;2531 return error.AnalysisFail;
2516 },2532 },
...@@ -2547,24 +2563,25 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl: *Module.Decl...@@ -2547,24 +2563,25 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl: *Module.Decl
2547pub fn updateDeclExports(2563pub fn updateDeclExports(
2548 self: *Elf,2564 self: *Elf,
2549 module: *Module,2565 module: *Module,
2550 decl: *Module.Decl,2566 decl_index: Module.Decl.Index,
2551 exports: []const *Module.Export,2567 exports: []const *Module.Export,
2552) !void {2568) !void {
2553 if (build_options.skip_non_native and builtin.object_format != .elf) {2569 if (build_options.skip_non_native and builtin.object_format != .elf) {
2554 @panic("Attempted to compile for object format that was disabled by build configuration");2570 @panic("Attempted to compile for object format that was disabled by build configuration");
2555 }2571 }
2556 if (build_options.have_llvm) {2572 if (build_options.have_llvm) {
2557 if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(module, decl, exports);2573 if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(module, decl_index, exports);
2558 }2574 }
25592575
2560 const tracy = trace(@src());2576 const tracy = trace(@src());
2561 defer tracy.end();2577 defer tracy.end();
25622578
2563 try self.global_symbols.ensureUnusedCapacity(self.base.allocator, exports.len);2579 try self.global_symbols.ensureUnusedCapacity(self.base.allocator, exports.len);
2580 const decl = module.declPtr(decl_index);
2564 if (decl.link.elf.local_sym_index == 0) return;2581 if (decl.link.elf.local_sym_index == 0) return;
2565 const decl_sym = self.local_symbols.items[decl.link.elf.local_sym_index];2582 const decl_sym = self.local_symbols.items[decl.link.elf.local_sym_index];
25662583
2567 const decl_ptr = self.decls.getPtr(decl).?;2584 const decl_ptr = self.decls.getPtr(decl_index).?;
2568 if (decl_ptr.* == null) {2585 if (decl_ptr.* == null) {
2569 decl_ptr.* = try self.getDeclPhdrIndex(decl);2586 decl_ptr.* = try self.getDeclPhdrIndex(decl);
2570 }2587 }
...@@ -2633,12 +2650,11 @@ pub fn updateDeclExports(...@@ -2633,12 +2650,11 @@ pub fn updateDeclExports(
2633}2650}
26342651
2635/// Must be called only after a successful call to `updateDecl`.2652/// Must be called only after a successful call to `updateDecl`.
2636pub fn updateDeclLineNumber(self: *Elf, module: *Module, decl: *const Module.Decl) !void {2653pub fn updateDeclLineNumber(self: *Elf, mod: *Module, decl: *const Module.Decl) !void {
2637 _ = module;
2638 const tracy = trace(@src());2654 const tracy = trace(@src());
2639 defer tracy.end();2655 defer tracy.end();
26402656
2641 const decl_name = try decl.getFullyQualifiedName(self.base.allocator);2657 const decl_name = try decl.getFullyQualifiedName(mod);
2642 defer self.base.allocator.free(decl_name);2658 defer self.base.allocator.free(decl_name);
26432659
2644 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });2660 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });
src/link/MachO.zig+65-47
...@@ -247,14 +247,14 @@ unnamed_const_atoms: UnnamedConstTable = .{},...@@ -247,14 +247,14 @@ unnamed_const_atoms: UnnamedConstTable = .{},
247/// We store them here so that we can properly dispose of any allocated247/// We store them here so that we can properly dispose of any allocated
248/// memory within the atom in the incremental linker.248/// memory within the atom in the incremental linker.
249/// TODO consolidate this.249/// TODO consolidate this.
250decls: std.AutoArrayHashMapUnmanaged(*Module.Decl, ?MatchingSection) = .{},250decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, ?MatchingSection) = .{},
251251
252const Entry = struct {252const Entry = struct {
253 target: Atom.Relocation.Target,253 target: Atom.Relocation.Target,
254 atom: *Atom,254 atom: *Atom,
255};255};
256256
257const UnnamedConstTable = std.AutoHashMapUnmanaged(*Module.Decl, std.ArrayListUnmanaged(*Atom));257const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(*Atom));
258258
259const PendingUpdate = union(enum) {259const PendingUpdate = union(enum) {
260 resolve_undef: u32,260 resolve_undef: u32,
...@@ -3451,10 +3451,15 @@ pub fn deinit(self: *MachO) void {...@@ -3451,10 +3451,15 @@ pub fn deinit(self: *MachO) void {
3451 }3451 }
3452 self.atom_free_lists.deinit(self.base.allocator);3452 self.atom_free_lists.deinit(self.base.allocator);
3453 }3453 }
3454 for (self.decls.keys()) |decl| {3454 if (self.base.options.module) |mod| {
3455 decl.link.macho.deinit(self.base.allocator);3455 for (self.decls.keys()) |decl_index| {
3456 const decl = mod.declPtr(decl_index);
3457 decl.link.macho.deinit(self.base.allocator);
3458 }
3459 self.decls.deinit(self.base.allocator);
3460 } else {
3461 assert(self.decls.count() == 0);
3456 }3462 }
3457 self.decls.deinit(self.base.allocator);
34583463
3459 {3464 {
3460 var it = self.unnamed_const_atoms.valueIterator();3465 var it = self.unnamed_const_atoms.valueIterator();
...@@ -3652,13 +3657,14 @@ pub fn allocateTlvPtrEntry(self: *MachO, target: Atom.Relocation.Target) !u32 {...@@ -3652,13 +3657,14 @@ pub fn allocateTlvPtrEntry(self: *MachO, target: Atom.Relocation.Target) !u32 {
3652 return index;3657 return index;
3653}3658}
36543659
3655pub fn allocateDeclIndexes(self: *MachO, decl: *Module.Decl) !void {3660pub fn allocateDeclIndexes(self: *MachO, decl_index: Module.Decl.Index) !void {
3656 if (self.llvm_object) |_| return;3661 if (self.llvm_object) |_| return;
3662 const decl = self.base.options.module.?.declPtr(decl_index);
3657 if (decl.link.macho.local_sym_index != 0) return;3663 if (decl.link.macho.local_sym_index != 0) return;
36583664
3659 decl.link.macho.local_sym_index = try self.allocateLocalSymbol();3665 decl.link.macho.local_sym_index = try self.allocateLocalSymbol();
3660 try self.atom_by_index_table.putNoClobber(self.base.allocator, decl.link.macho.local_sym_index, &decl.link.macho);3666 try self.atom_by_index_table.putNoClobber(self.base.allocator, decl.link.macho.local_sym_index, &decl.link.macho);
3661 try self.decls.putNoClobber(self.base.allocator, decl, null);3667 try self.decls.putNoClobber(self.base.allocator, decl_index, null);
36623668
3663 const got_target = .{ .local = decl.link.macho.local_sym_index };3669 const got_target = .{ .local = decl.link.macho.local_sym_index };
3664 const got_index = try self.allocateGotEntry(got_target);3670 const got_index = try self.allocateGotEntry(got_target);
...@@ -3676,8 +3682,9 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv...@@ -3676,8 +3682,9 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv
3676 const tracy = trace(@src());3682 const tracy = trace(@src());
3677 defer tracy.end();3683 defer tracy.end();
36783684
3679 const decl = func.owner_decl;3685 const decl_index = func.owner_decl;
3680 self.freeUnnamedConsts(decl);3686 const decl = module.declPtr(decl_index);
3687 self.freeUnnamedConsts(decl_index);
36813688
3682 // TODO clearing the code and relocs buffer should probably be orchestrated3689 // TODO clearing the code and relocs buffer should probably be orchestrated
3683 // in a different, smarter, more automatic way somewhere else, in a more centralised3690 // in a different, smarter, more automatic way somewhere else, in a more centralised
...@@ -3690,7 +3697,7 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv...@@ -3690,7 +3697,7 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv
3690 defer code_buffer.deinit();3697 defer code_buffer.deinit();
36913698
3692 var decl_state = if (self.d_sym) |*d_sym|3699 var decl_state = if (self.d_sym) |*d_sym|
3693 try d_sym.dwarf.initDeclState(decl)3700 try d_sym.dwarf.initDeclState(module, decl)
3694 else3701 else
3695 null;3702 null;
3696 defer if (decl_state) |*ds| ds.deinit();3703 defer if (decl_state) |*ds| ds.deinit();
...@@ -3708,12 +3715,12 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv...@@ -3708,12 +3715,12 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv
3708 },3715 },
3709 .fail => |em| {3716 .fail => |em| {
3710 decl.analysis = .codegen_failure;3717 decl.analysis = .codegen_failure;
3711 try module.failed_decls.put(module.gpa, decl, em);3718 try module.failed_decls.put(module.gpa, decl_index, em);
3712 return;3719 return;
3713 },3720 },
3714 }3721 }
37153722
3716 const symbol = try self.placeDecl(decl, decl.link.macho.code.items.len);3723 const symbol = try self.placeDecl(decl_index, decl.link.macho.code.items.len);
37173724
3718 if (decl_state) |*ds| {3725 if (decl_state) |*ds| {
3719 try self.d_sym.?.dwarf.commitDeclState(3726 try self.d_sym.?.dwarf.commitDeclState(
...@@ -3728,22 +3735,23 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv...@@ -3728,22 +3735,23 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv
37283735
3729 // Since we updated the vaddr and the size, each corresponding export symbol also3736 // Since we updated the vaddr and the size, each corresponding export symbol also
3730 // needs to be updated.3737 // needs to be updated.
3731 const decl_exports = module.decl_exports.get(decl) orelse &[0]*Module.Export{};3738 const decl_exports = module.decl_exports.get(decl_index) orelse &[0]*Module.Export{};
3732 try self.updateDeclExports(module, decl, decl_exports);3739 try self.updateDeclExports(module, decl_index, decl_exports);
3733}3740}
37343741
3735pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl: *Module.Decl) !u32 {3742pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Module.Decl.Index) !u32 {
3736 var code_buffer = std.ArrayList(u8).init(self.base.allocator);3743 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
3737 defer code_buffer.deinit();3744 defer code_buffer.deinit();
37383745
3739 const module = self.base.options.module.?;3746 const module = self.base.options.module.?;
3740 const gop = try self.unnamed_const_atoms.getOrPut(self.base.allocator, decl);3747 const gop = try self.unnamed_const_atoms.getOrPut(self.base.allocator, decl_index);
3741 if (!gop.found_existing) {3748 if (!gop.found_existing) {
3742 gop.value_ptr.* = .{};3749 gop.value_ptr.* = .{};
3743 }3750 }
3744 const unnamed_consts = gop.value_ptr;3751 const unnamed_consts = gop.value_ptr;
37453752
3746 const decl_name = try decl.getFullyQualifiedName(self.base.allocator);3753 const decl = module.declPtr(decl_index);
3754 const decl_name = try decl.getFullyQualifiedName(module);
3747 defer self.base.allocator.free(decl_name);3755 defer self.base.allocator.free(decl_name);
37483756
3749 const name_str_index = blk: {3757 const name_str_index = blk: {
...@@ -3769,7 +3777,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl: *Module.De...@@ -3769,7 +3777,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl: *Module.De
3769 .appended => code_buffer.items,3777 .appended => code_buffer.items,
3770 .fail => |em| {3778 .fail => |em| {
3771 decl.analysis = .codegen_failure;3779 decl.analysis = .codegen_failure;
3772 try module.failed_decls.put(module.gpa, decl, em);3780 try module.failed_decls.put(module.gpa, decl_index, em);
3773 log.err("{s}", .{em.msg});3781 log.err("{s}", .{em.msg});
3774 return error.AnalysisFail;3782 return error.AnalysisFail;
3775 },3783 },
...@@ -3800,16 +3808,18 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl: *Module.De...@@ -3800,16 +3808,18 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl: *Module.De
3800 return atom.local_sym_index;3808 return atom.local_sym_index;
3801}3809}
38023810
3803pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {3811pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index) !void {
3804 if (build_options.skip_non_native and builtin.object_format != .macho) {3812 if (build_options.skip_non_native and builtin.object_format != .macho) {
3805 @panic("Attempted to compile for object format that was disabled by build configuration");3813 @panic("Attempted to compile for object format that was disabled by build configuration");
3806 }3814 }
3807 if (build_options.have_llvm) {3815 if (build_options.have_llvm) {
3808 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(module, decl);3816 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(module, decl_index);
3809 }3817 }
3810 const tracy = trace(@src());3818 const tracy = trace(@src());
3811 defer tracy.end();3819 defer tracy.end();
38123820
3821 const decl = module.declPtr(decl_index);
3822
3813 if (decl.val.tag() == .extern_fn) {3823 if (decl.val.tag() == .extern_fn) {
3814 return; // TODO Should we do more when front-end analyzed extern decl?3824 return; // TODO Should we do more when front-end analyzed extern decl?
3815 }3825 }
...@@ -3824,7 +3834,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {...@@ -3824,7 +3834,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
3824 defer code_buffer.deinit();3834 defer code_buffer.deinit();
38253835
3826 var decl_state: ?Dwarf.DeclState = if (self.d_sym) |*d_sym|3836 var decl_state: ?Dwarf.DeclState = if (self.d_sym) |*d_sym|
3827 try d_sym.dwarf.initDeclState(decl)3837 try d_sym.dwarf.initDeclState(module, decl)
3828 else3838 else
3829 null;3839 null;
3830 defer if (decl_state) |*ds| ds.deinit();3840 defer if (decl_state) |*ds| ds.deinit();
...@@ -3862,12 +3872,12 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {...@@ -3862,12 +3872,12 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
3862 },3872 },
3863 .fail => |em| {3873 .fail => |em| {
3864 decl.analysis = .codegen_failure;3874 decl.analysis = .codegen_failure;
3865 try module.failed_decls.put(module.gpa, decl, em);3875 try module.failed_decls.put(module.gpa, decl_index, em);
3866 return;3876 return;
3867 },3877 },
3868 }3878 }
3869 };3879 };
3870 const symbol = try self.placeDecl(decl, code.len);3880 const symbol = try self.placeDecl(decl_index, code.len);
38713881
3872 if (decl_state) |*ds| {3882 if (decl_state) |*ds| {
3873 try self.d_sym.?.dwarf.commitDeclState(3883 try self.d_sym.?.dwarf.commitDeclState(
...@@ -3882,13 +3892,13 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {...@@ -3882,13 +3892,13 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
38823892
3883 // Since we updated the vaddr and the size, each corresponding export symbol also3893 // Since we updated the vaddr and the size, each corresponding export symbol also
3884 // needs to be updated.3894 // needs to be updated.
3885 const decl_exports = module.decl_exports.get(decl) orelse &[0]*Module.Export{};3895 const decl_exports = module.decl_exports.get(decl_index) orelse &[0]*Module.Export{};
3886 try self.updateDeclExports(module, decl, decl_exports);3896 try self.updateDeclExports(module, decl_index, decl_exports);
3887}3897}
38883898
3889/// Checks if the value, or any of its embedded values stores a pointer, and thus requires3899/// Checks if the value, or any of its embedded values stores a pointer, and thus requires
3890/// a rebase opcode for the dynamic linker.3900/// a rebase opcode for the dynamic linker.
3891fn needsPointerRebase(ty: Type, val: Value, target: std.Target) bool {3901fn needsPointerRebase(ty: Type, val: Value, mod: *Module) bool {
3892 if (ty.zigTypeTag() == .Fn) {3902 if (ty.zigTypeTag() == .Fn) {
3893 return false;3903 return false;
3894 }3904 }
...@@ -3903,8 +3913,8 @@ fn needsPointerRebase(ty: Type, val: Value, target: std.Target) bool {...@@ -3903,8 +3913,8 @@ fn needsPointerRebase(ty: Type, val: Value, target: std.Target) bool {
3903 if (ty.arrayLen() == 0) return false;3913 if (ty.arrayLen() == 0) return false;
3904 const elem_ty = ty.childType();3914 const elem_ty = ty.childType();
3905 var elem_value_buf: Value.ElemValueBuffer = undefined;3915 var elem_value_buf: Value.ElemValueBuffer = undefined;
3906 const elem_val = val.elemValueBuffer(0, &elem_value_buf);3916 const elem_val = val.elemValueBuffer(mod, 0, &elem_value_buf);
3907 return needsPointerRebase(elem_ty, elem_val, target);3917 return needsPointerRebase(elem_ty, elem_val, mod);
3908 },3918 },
3909 .Struct => {3919 .Struct => {
3910 const fields = ty.structFields().values();3920 const fields = ty.structFields().values();
...@@ -3912,7 +3922,7 @@ fn needsPointerRebase(ty: Type, val: Value, target: std.Target) bool {...@@ -3912,7 +3922,7 @@ fn needsPointerRebase(ty: Type, val: Value, target: std.Target) bool {
3912 if (val.castTag(.aggregate)) |payload| {3922 if (val.castTag(.aggregate)) |payload| {
3913 const field_values = payload.data;3923 const field_values = payload.data;
3914 for (field_values) |field_val, i| {3924 for (field_values) |field_val, i| {
3915 if (needsPointerRebase(fields[i].ty, field_val, target)) return true;3925 if (needsPointerRebase(fields[i].ty, field_val, mod)) return true;
3916 } else return false;3926 } else return false;
3917 } else return false;3927 } else return false;
3918 },3928 },
...@@ -3921,18 +3931,18 @@ fn needsPointerRebase(ty: Type, val: Value, target: std.Target) bool {...@@ -3921,18 +3931,18 @@ fn needsPointerRebase(ty: Type, val: Value, target: std.Target) bool {
3921 const sub_val = payload.data;3931 const sub_val = payload.data;
3922 var buffer: Type.Payload.ElemType = undefined;3932 var buffer: Type.Payload.ElemType = undefined;
3923 const sub_ty = ty.optionalChild(&buffer);3933 const sub_ty = ty.optionalChild(&buffer);
3924 return needsPointerRebase(sub_ty, sub_val, target);3934 return needsPointerRebase(sub_ty, sub_val, mod);
3925 } else return false;3935 } else return false;
3926 },3936 },
3927 .Union => {3937 .Union => {
3928 const union_obj = val.cast(Value.Payload.Union).?.data;3938 const union_obj = val.cast(Value.Payload.Union).?.data;
3929 const active_field_ty = ty.unionFieldType(union_obj.tag, target);3939 const active_field_ty = ty.unionFieldType(union_obj.tag, mod);
3930 return needsPointerRebase(active_field_ty, union_obj.val, target);3940 return needsPointerRebase(active_field_ty, union_obj.val, mod);
3931 },3941 },
3932 .ErrorUnion => {3942 .ErrorUnion => {
3933 if (val.castTag(.eu_payload)) |payload| {3943 if (val.castTag(.eu_payload)) |payload| {
3934 const payload_ty = ty.errorUnionPayload();3944 const payload_ty = ty.errorUnionPayload();
3935 return needsPointerRebase(payload_ty, payload.data, target);3945 return needsPointerRebase(payload_ty, payload.data, mod);
3936 } else return false;3946 } else return false;
3937 },3947 },
3938 else => return false,3948 else => return false,
...@@ -3942,6 +3952,7 @@ fn needsPointerRebase(ty: Type, val: Value, target: std.Target) bool {...@@ -3942,6 +3952,7 @@ fn needsPointerRebase(ty: Type, val: Value, target: std.Target) bool {
3942fn getMatchingSectionAtom(self: *MachO, atom: *Atom, name: []const u8, ty: Type, val: Value) !MatchingSection {3952fn getMatchingSectionAtom(self: *MachO, atom: *Atom, name: []const u8, ty: Type, val: Value) !MatchingSection {
3943 const code = atom.code.items;3953 const code = atom.code.items;
3944 const target = self.base.options.target;3954 const target = self.base.options.target;
3955 const mod = self.base.options.module.?;
3945 const alignment = ty.abiAlignment(target);3956 const alignment = ty.abiAlignment(target);
3946 const align_log_2 = math.log2(alignment);3957 const align_log_2 = math.log2(alignment);
3947 const zig_ty = ty.zigTypeTag();3958 const zig_ty = ty.zigTypeTag();
...@@ -3969,7 +3980,7 @@ fn getMatchingSectionAtom(self: *MachO, atom: *Atom, name: []const u8, ty: Type,...@@ -3969,7 +3980,7 @@ fn getMatchingSectionAtom(self: *MachO, atom: *Atom, name: []const u8, ty: Type,
3969 };3980 };
3970 }3981 }
39713982
3972 if (needsPointerRebase(ty, val, target)) {3983 if (needsPointerRebase(ty, val, mod)) {
3973 break :blk (try self.getMatchingSection(.{3984 break :blk (try self.getMatchingSection(.{
3974 .segname = makeStaticString("__DATA_CONST"),3985 .segname = makeStaticString("__DATA_CONST"),
3975 .sectname = makeStaticString("__const"),3986 .sectname = makeStaticString("__const"),
...@@ -4025,15 +4036,17 @@ fn getMatchingSectionAtom(self: *MachO, atom: *Atom, name: []const u8, ty: Type,...@@ -4025,15 +4036,17 @@ fn getMatchingSectionAtom(self: *MachO, atom: *Atom, name: []const u8, ty: Type,
4025 return match;4036 return match;
4026}4037}
40274038
4028fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64 {4039fn placeDecl(self: *MachO, decl_index: Module.Decl.Index, code_len: usize) !*macho.nlist_64 {
4040 const module = self.base.options.module.?;
4041 const decl = module.declPtr(decl_index);
4029 const required_alignment = decl.ty.abiAlignment(self.base.options.target);4042 const required_alignment = decl.ty.abiAlignment(self.base.options.target);
4030 assert(decl.link.macho.local_sym_index != 0); // Caller forgot to call allocateDeclIndexes()4043 assert(decl.link.macho.local_sym_index != 0); // Caller forgot to call allocateDeclIndexes()
4031 const symbol = &self.locals.items[decl.link.macho.local_sym_index];4044 const symbol = &self.locals.items[decl.link.macho.local_sym_index];
40324045
4033 const sym_name = try decl.getFullyQualifiedName(self.base.allocator);4046 const sym_name = try decl.getFullyQualifiedName(module);
4034 defer self.base.allocator.free(sym_name);4047 defer self.base.allocator.free(sym_name);
40354048
4036 const decl_ptr = self.decls.getPtr(decl).?;4049 const decl_ptr = self.decls.getPtr(decl_index).?;
4037 if (decl_ptr.* == null) {4050 if (decl_ptr.* == null) {
4038 decl_ptr.* = try self.getMatchingSectionAtom(&decl.link.macho, sym_name, decl.ty, decl.val);4051 decl_ptr.* = try self.getMatchingSectionAtom(&decl.link.macho, sym_name, decl.ty, decl.val);
4039 }4052 }
...@@ -4101,19 +4114,20 @@ pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl: *const Module.D...@@ -4101,19 +4114,20 @@ pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl: *const Module.D
4101pub fn updateDeclExports(4114pub fn updateDeclExports(
4102 self: *MachO,4115 self: *MachO,
4103 module: *Module,4116 module: *Module,
4104 decl: *Module.Decl,4117 decl_index: Module.Decl.Index,
4105 exports: []const *Module.Export,4118 exports: []const *Module.Export,
4106) !void {4119) !void {
4107 if (build_options.skip_non_native and builtin.object_format != .macho) {4120 if (build_options.skip_non_native and builtin.object_format != .macho) {
4108 @panic("Attempted to compile for object format that was disabled by build configuration");4121 @panic("Attempted to compile for object format that was disabled by build configuration");
4109 }4122 }
4110 if (build_options.have_llvm) {4123 if (build_options.have_llvm) {
4111 if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(module, decl, exports);4124 if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(module, decl_index, exports);
4112 }4125 }
4113 const tracy = trace(@src());4126 const tracy = trace(@src());
4114 defer tracy.end();4127 defer tracy.end();
41154128
4116 try self.globals.ensureUnusedCapacity(self.base.allocator, exports.len);4129 try self.globals.ensureUnusedCapacity(self.base.allocator, exports.len);
4130 const decl = module.declPtr(decl_index);
4117 if (decl.link.macho.local_sym_index == 0) return;4131 if (decl.link.macho.local_sym_index == 0) return;
4118 const decl_sym = &self.locals.items[decl.link.macho.local_sym_index];4132 const decl_sym = &self.locals.items[decl.link.macho.local_sym_index];
41194133
...@@ -4250,9 +4264,8 @@ pub fn deleteExport(self: *MachO, exp: Export) void {...@@ -4250,9 +4264,8 @@ pub fn deleteExport(self: *MachO, exp: Export) void {
4250 global.n_value = 0;4264 global.n_value = 0;
4251}4265}
42524266
4253fn freeUnnamedConsts(self: *MachO, decl: *Module.Decl) void {4267fn freeUnnamedConsts(self: *MachO, decl_index: Module.Decl.Index) void {
4254 log.debug("freeUnnamedConsts for decl {*}", .{decl});4268 const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return;
4255 const unnamed_consts = self.unnamed_const_atoms.getPtr(decl) orelse return;
4256 for (unnamed_consts.items) |atom| {4269 for (unnamed_consts.items) |atom| {
4257 self.freeAtom(atom, .{4270 self.freeAtom(atom, .{
4258 .seg = self.text_segment_cmd_index.?,4271 .seg = self.text_segment_cmd_index.?,
...@@ -4267,15 +4280,17 @@ fn freeUnnamedConsts(self: *MachO, decl: *Module.Decl) void {...@@ -4267,15 +4280,17 @@ fn freeUnnamedConsts(self: *MachO, decl: *Module.Decl) void {
4267 unnamed_consts.clearAndFree(self.base.allocator);4280 unnamed_consts.clearAndFree(self.base.allocator);
4268}4281}
42694282
4270pub fn freeDecl(self: *MachO, decl: *Module.Decl) void {4283pub fn freeDecl(self: *MachO, decl_index: Module.Decl.Index) void {
4271 if (build_options.have_llvm) {4284 if (build_options.have_llvm) {
4272 if (self.llvm_object) |llvm_object| return llvm_object.freeDecl(decl);4285 if (self.llvm_object) |llvm_object| return llvm_object.freeDecl(decl_index);
4273 }4286 }
4287 const mod = self.base.options.module.?;
4288 const decl = mod.declPtr(decl_index);
4274 log.debug("freeDecl {*}", .{decl});4289 log.debug("freeDecl {*}", .{decl});
4275 const kv = self.decls.fetchSwapRemove(decl);4290 const kv = self.decls.fetchSwapRemove(decl_index);
4276 if (kv.?.value) |match| {4291 if (kv.?.value) |match| {
4277 self.freeAtom(&decl.link.macho, match, false);4292 self.freeAtom(&decl.link.macho, match, false);
4278 self.freeUnnamedConsts(decl);4293 self.freeUnnamedConsts(decl_index);
4279 }4294 }
4280 // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.4295 // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.
4281 if (decl.link.macho.local_sym_index != 0) {4296 if (decl.link.macho.local_sym_index != 0) {
...@@ -4307,7 +4322,10 @@ pub fn freeDecl(self: *MachO, decl: *Module.Decl) void {...@@ -4307,7 +4322,10 @@ pub fn freeDecl(self: *MachO, decl: *Module.Decl) void {
4307 }4322 }
4308}4323}
43094324
4310pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl, reloc_info: File.RelocInfo) !u64 {4325pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: File.RelocInfo) !u64 {
4326 const mod = self.base.options.module.?;
4327 const decl = mod.declPtr(decl_index);
4328
4311 assert(self.llvm_object == null);4329 assert(self.llvm_object == null);
4312 assert(decl.link.macho.local_sym_index != 0);4330 assert(decl.link.macho.local_sym_index != 0);
43134331
src/link/NvPtx.zig+6-6
...@@ -74,27 +74,27 @@ pub fn updateFunc(self: *NvPtx, module: *Module, func: *Module.Fn, air: Air, liv...@@ -74,27 +74,27 @@ pub fn updateFunc(self: *NvPtx, module: *Module, func: *Module.Fn, air: Air, liv
74 try self.llvm_object.updateFunc(module, func, air, liveness);74 try self.llvm_object.updateFunc(module, func, air, liveness);
75}75}
7676
77pub fn updateDecl(self: *NvPtx, module: *Module, decl: *Module.Decl) !void {77pub fn updateDecl(self: *NvPtx, module: *Module, decl_index: Module.Decl.Index) !void {
78 if (!build_options.have_llvm) return;78 if (!build_options.have_llvm) return;
79 return self.llvm_object.updateDecl(module, decl);79 return self.llvm_object.updateDecl(module, decl_index);
80}80}
8181
82pub fn updateDeclExports(82pub fn updateDeclExports(
83 self: *NvPtx,83 self: *NvPtx,
84 module: *Module,84 module: *Module,
85 decl: *const Module.Decl,85 decl_index: Module.Decl.Index,
86 exports: []const *Module.Export,86 exports: []const *Module.Export,
87) !void {87) !void {
88 if (!build_options.have_llvm) return;88 if (!build_options.have_llvm) return;
89 if (build_options.skip_non_native and builtin.object_format != .nvptx) {89 if (build_options.skip_non_native and builtin.object_format != .nvptx) {
90 @panic("Attempted to compile for object format that was disabled by build configuration");90 @panic("Attempted to compile for object format that was disabled by build configuration");
91 }91 }
92 return self.llvm_object.updateDeclExports(module, decl, exports);92 return self.llvm_object.updateDeclExports(module, decl_index, exports);
93}93}
9494
95pub fn freeDecl(self: *NvPtx, decl: *Module.Decl) void {95pub fn freeDecl(self: *NvPtx, decl_index: Module.Decl.Index) void {
96 if (!build_options.have_llvm) return;96 if (!build_options.have_llvm) return;
97 return self.llvm_object.freeDecl(decl);97 return self.llvm_object.freeDecl(decl_index);
98}98}
9999
100pub fn flush(self: *NvPtx, comp: *Compilation, prog_node: *std.Progress.Node) !void {100pub fn flush(self: *NvPtx, comp: *Compilation, prog_node: *std.Progress.Node) !void {
src/link/Plan9.zig+57-37
...@@ -59,9 +59,9 @@ path_arena: std.heap.ArenaAllocator,...@@ -59,9 +59,9 @@ path_arena: std.heap.ArenaAllocator,
59/// If we group the decls by file, it makes it really easy to do this (put the symbol in the correct place)59/// If we group the decls by file, it makes it really easy to do this (put the symbol in the correct place)
60fn_decl_table: std.AutoArrayHashMapUnmanaged(60fn_decl_table: std.AutoArrayHashMapUnmanaged(
61 *Module.File,61 *Module.File,
62 struct { sym_index: u32, functions: std.AutoArrayHashMapUnmanaged(*Module.Decl, FnDeclOutput) = .{} },62 struct { sym_index: u32, functions: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, FnDeclOutput) = .{} },
63) = .{},63) = .{},
64data_decl_table: std.AutoArrayHashMapUnmanaged(*Module.Decl, []const u8) = .{},64data_decl_table: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, []const u8) = .{},
6565
66hdr: aout.ExecHdr = undefined,66hdr: aout.ExecHdr = undefined,
6767
...@@ -162,11 +162,13 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Plan9 {...@@ -162,11 +162,13 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Plan9 {
162 return self;162 return self;
163}163}
164164
165fn putFn(self: *Plan9, decl: *Module.Decl, out: FnDeclOutput) !void {165fn putFn(self: *Plan9, decl_index: Module.Decl.Index, out: FnDeclOutput) !void {
166 const gpa = self.base.allocator;166 const gpa = self.base.allocator;
167 const mod = self.base.options.module.?;
168 const decl = mod.declPtr(decl_index);
167 const fn_map_res = try self.fn_decl_table.getOrPut(gpa, decl.getFileScope());169 const fn_map_res = try self.fn_decl_table.getOrPut(gpa, decl.getFileScope());
168 if (fn_map_res.found_existing) {170 if (fn_map_res.found_existing) {
169 try fn_map_res.value_ptr.functions.put(gpa, decl, out);171 try fn_map_res.value_ptr.functions.put(gpa, decl_index, out);
170 } else {172 } else {
171 const file = decl.getFileScope();173 const file = decl.getFileScope();
172 const arena = self.path_arena.allocator();174 const arena = self.path_arena.allocator();
...@@ -178,7 +180,7 @@ fn putFn(self: *Plan9, decl: *Module.Decl, out: FnDeclOutput) !void {...@@ -178,7 +180,7 @@ fn putFn(self: *Plan9, decl: *Module.Decl, out: FnDeclOutput) !void {
178 break :blk @intCast(u32, self.syms.items.len - 1);180 break :blk @intCast(u32, self.syms.items.len - 1);
179 },181 },
180 };182 };
181 try fn_map_res.value_ptr.functions.put(gpa, decl, out);183 try fn_map_res.value_ptr.functions.put(gpa, decl_index, out);
182184
183 var a = std.ArrayList(u8).init(arena);185 var a = std.ArrayList(u8).init(arena);
184 errdefer a.deinit();186 errdefer a.deinit();
...@@ -229,9 +231,10 @@ pub fn updateFunc(self: *Plan9, module: *Module, func: *Module.Fn, air: Air, liv...@@ -229,9 +231,10 @@ pub fn updateFunc(self: *Plan9, module: *Module, func: *Module.Fn, air: Air, liv
229 @panic("Attempted to compile for object format that was disabled by build configuration");231 @panic("Attempted to compile for object format that was disabled by build configuration");
230 }232 }
231233
232 const decl = func.owner_decl;234 const decl_index = func.owner_decl;
235 const decl = module.declPtr(decl_index);
233236
234 try self.seeDecl(decl);237 try self.seeDecl(decl_index);
235 log.debug("codegen decl {*} ({s})", .{ decl, decl.name });238 log.debug("codegen decl {*} ({s})", .{ decl, decl.name });
236239
237 var code_buffer = std.ArrayList(u8).init(self.base.allocator);240 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
...@@ -262,7 +265,7 @@ pub fn updateFunc(self: *Plan9, module: *Module, func: *Module.Fn, air: Air, liv...@@ -262,7 +265,7 @@ pub fn updateFunc(self: *Plan9, module: *Module, func: *Module.Fn, air: Air, liv
262 .appended => code_buffer.toOwnedSlice(),265 .appended => code_buffer.toOwnedSlice(),
263 .fail => |em| {266 .fail => |em| {
264 decl.analysis = .codegen_failure;267 decl.analysis = .codegen_failure;
265 try module.failed_decls.put(module.gpa, decl, em);268 try module.failed_decls.put(module.gpa, decl_index, em);
266 return;269 return;
267 },270 },
268 };271 };
...@@ -272,19 +275,21 @@ pub fn updateFunc(self: *Plan9, module: *Module, func: *Module.Fn, air: Air, liv...@@ -272,19 +275,21 @@ pub fn updateFunc(self: *Plan9, module: *Module, func: *Module.Fn, air: Air, liv
272 .start_line = start_line.?,275 .start_line = start_line.?,
273 .end_line = end_line,276 .end_line = end_line,
274 };277 };
275 try self.putFn(decl, out);278 try self.putFn(decl_index, out);
276 return self.updateFinish(decl);279 return self.updateFinish(decl);
277}280}
278281
279pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl: *Module.Decl) !u32 {282pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: Module.Decl.Index) !u32 {
280 _ = self;283 _ = self;
281 _ = tv;284 _ = tv;
282 _ = decl;285 _ = decl_index;
283 log.debug("TODO lowerUnnamedConst for Plan9", .{});286 log.debug("TODO lowerUnnamedConst for Plan9", .{});
284 return error.AnalysisFail;287 return error.AnalysisFail;
285}288}
286289
287pub fn updateDecl(self: *Plan9, module: *Module, decl: *Module.Decl) !void {290pub fn updateDecl(self: *Plan9, module: *Module, decl_index: Module.Decl.Index) !void {
291 const decl = module.declPtr(decl_index);
292
288 if (decl.val.tag() == .extern_fn) {293 if (decl.val.tag() == .extern_fn) {
289 return; // TODO Should we do more when front-end analyzed extern decl?294 return; // TODO Should we do more when front-end analyzed extern decl?
290 }295 }
...@@ -295,7 +300,7 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl: *Module.Decl) !void {...@@ -295,7 +300,7 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl: *Module.Decl) !void {
295 }300 }
296 }301 }
297302
298 try self.seeDecl(decl);303 try self.seeDecl(decl_index);
299304
300 log.debug("codegen decl {*} ({s})", .{ decl, decl.name });305 log.debug("codegen decl {*} ({s})", .{ decl, decl.name });
301306
...@@ -315,13 +320,13 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl: *Module.Decl) !void {...@@ -315,13 +320,13 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl: *Module.Decl) !void {
315 .appended => code_buffer.items,320 .appended => code_buffer.items,
316 .fail => |em| {321 .fail => |em| {
317 decl.analysis = .codegen_failure;322 decl.analysis = .codegen_failure;
318 try module.failed_decls.put(module.gpa, decl, em);323 try module.failed_decls.put(module.gpa, decl_index, em);
319 return;324 return;
320 },325 },
321 };326 };
322 var duped_code = try self.base.allocator.dupe(u8, code);327 var duped_code = try self.base.allocator.dupe(u8, code);
323 errdefer self.base.allocator.free(duped_code);328 errdefer self.base.allocator.free(duped_code);
324 try self.data_decl_table.put(self.base.allocator, decl, duped_code);329 try self.data_decl_table.put(self.base.allocator, decl_index, duped_code);
325 return self.updateFinish(decl);330 return self.updateFinish(decl);
326}331}
327/// called at the end of update{Decl,Func}332/// called at the end of update{Decl,Func}
...@@ -435,7 +440,8 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No...@@ -435,7 +440,8 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
435 while (it_file.next()) |fentry| {440 while (it_file.next()) |fentry| {
436 var it = fentry.value_ptr.functions.iterator();441 var it = fentry.value_ptr.functions.iterator();
437 while (it.next()) |entry| {442 while (it.next()) |entry| {
438 const decl = entry.key_ptr.*;443 const decl_index = entry.key_ptr.*;
444 const decl = mod.declPtr(decl_index);
439 const out = entry.value_ptr.*;445 const out = entry.value_ptr.*;
440 log.debug("write text decl {*} ({s}), lines {d} to {d}", .{ decl, decl.name, out.start_line + 1, out.end_line });446 log.debug("write text decl {*} ({s}), lines {d} to {d}", .{ decl, decl.name, out.start_line + 1, out.end_line });
441 {447 {
...@@ -462,7 +468,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No...@@ -462,7 +468,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
462 mem.writeInt(u64, got_table[decl.link.plan9.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());468 mem.writeInt(u64, got_table[decl.link.plan9.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());
463 }469 }
464 self.syms.items[decl.link.plan9.sym_index.?].value = off;470 self.syms.items[decl.link.plan9.sym_index.?].value = off;
465 if (mod.decl_exports.get(decl)) |exports| {471 if (mod.decl_exports.get(decl_index)) |exports| {
466 try self.addDeclExports(mod, decl, exports);472 try self.addDeclExports(mod, decl, exports);
467 }473 }
468 }474 }
...@@ -482,7 +488,8 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No...@@ -482,7 +488,8 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
482 {488 {
483 var it = self.data_decl_table.iterator();489 var it = self.data_decl_table.iterator();
484 while (it.next()) |entry| {490 while (it.next()) |entry| {
485 const decl = entry.key_ptr.*;491 const decl_index = entry.key_ptr.*;
492 const decl = mod.declPtr(decl_index);
486 const code = entry.value_ptr.*;493 const code = entry.value_ptr.*;
487 log.debug("write data decl {*} ({s})", .{ decl, decl.name });494 log.debug("write data decl {*} ({s})", .{ decl, decl.name });
488495
...@@ -498,7 +505,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No...@@ -498,7 +505,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
498 mem.writeInt(u64, got_table[decl.link.plan9.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());505 mem.writeInt(u64, got_table[decl.link.plan9.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());
499 }506 }
500 self.syms.items[decl.link.plan9.sym_index.?].value = off;507 self.syms.items[decl.link.plan9.sym_index.?].value = off;
501 if (mod.decl_exports.get(decl)) |exports| {508 if (mod.decl_exports.get(decl_index)) |exports| {
502 try self.addDeclExports(mod, decl, exports);509 try self.addDeclExports(mod, decl, exports);
503 }510 }
504 }511 }
...@@ -564,24 +571,25 @@ fn addDeclExports(...@@ -564,24 +571,25 @@ fn addDeclExports(
564 }571 }
565}572}
566573
567pub fn freeDecl(self: *Plan9, decl: *Module.Decl) void {574pub fn freeDecl(self: *Plan9, decl_index: Module.Decl.Index) void {
568 // TODO audit the lifetimes of decls table entries. It's possible to get575 // TODO audit the lifetimes of decls table entries. It's possible to get
569 // allocateDeclIndexes and then freeDecl without any updateDecl in between.576 // allocateDeclIndexes and then freeDecl without any updateDecl in between.
570 // However that is planned to change, see the TODO comment in Module.zig577 // However that is planned to change, see the TODO comment in Module.zig
571 // in the deleteUnusedDecl function.578 // in the deleteUnusedDecl function.
579 const mod = self.base.options.module.?;
580 const decl = mod.declPtr(decl_index);
572 const is_fn = (decl.val.tag() == .function);581 const is_fn = (decl.val.tag() == .function);
573 if (is_fn) {582 if (is_fn) {
574 var symidx_and_submap =583 var symidx_and_submap = self.fn_decl_table.get(decl.getFileScope()).?;
575 self.fn_decl_table.get(decl.getFileScope()).?;
576 var submap = symidx_and_submap.functions;584 var submap = symidx_and_submap.functions;
577 _ = submap.swapRemove(decl);585 _ = submap.swapRemove(decl_index);
578 if (submap.count() == 0) {586 if (submap.count() == 0) {
579 self.syms.items[symidx_and_submap.sym_index] = aout.Sym.undefined_symbol;587 self.syms.items[symidx_and_submap.sym_index] = aout.Sym.undefined_symbol;
580 self.syms_index_free_list.append(self.base.allocator, symidx_and_submap.sym_index) catch {};588 self.syms_index_free_list.append(self.base.allocator, symidx_and_submap.sym_index) catch {};
581 submap.deinit(self.base.allocator);589 submap.deinit(self.base.allocator);
582 }590 }
583 } else {591 } else {
584 _ = self.data_decl_table.swapRemove(decl);592 _ = self.data_decl_table.swapRemove(decl_index);
585 }593 }
586 if (decl.link.plan9.got_index) |i| {594 if (decl.link.plan9.got_index) |i| {
587 // TODO: if this catch {} is triggered, an assertion in flushModule will be triggered, because got_index_free_list will have the wrong length595 // TODO: if this catch {} is triggered, an assertion in flushModule will be triggered, because got_index_free_list will have the wrong length
...@@ -593,7 +601,9 @@ pub fn freeDecl(self: *Plan9, decl: *Module.Decl) void {...@@ -593,7 +601,9 @@ pub fn freeDecl(self: *Plan9, decl: *Module.Decl) void {
593 }601 }
594}602}
595603
596pub fn seeDecl(self: *Plan9, decl: *Module.Decl) !void {604pub fn seeDecl(self: *Plan9, decl_index: Module.Decl.Index) !void {
605 const mod = self.base.options.module.?;
606 const decl = mod.declPtr(decl_index);
597 if (decl.link.plan9.got_index == null) {607 if (decl.link.plan9.got_index == null) {
598 if (self.got_index_free_list.popOrNull()) |i| {608 if (self.got_index_free_list.popOrNull()) |i| {
599 decl.link.plan9.got_index = i;609 decl.link.plan9.got_index = i;
...@@ -607,14 +617,13 @@ pub fn seeDecl(self: *Plan9, decl: *Module.Decl) !void {...@@ -607,14 +617,13 @@ pub fn seeDecl(self: *Plan9, decl: *Module.Decl) !void {
607pub fn updateDeclExports(617pub fn updateDeclExports(
608 self: *Plan9,618 self: *Plan9,
609 module: *Module,619 module: *Module,
610 decl: *Module.Decl,620 decl_index: Module.Decl.Index,
611 exports: []const *Module.Export,621 exports: []const *Module.Export,
612) !void {622) !void {
613 try self.seeDecl(decl);623 try self.seeDecl(decl_index);
614 // we do all the things in flush624 // we do all the things in flush
615 _ = self;625 _ = self;
616 _ = module;626 _ = module;
617 _ = decl;
618 _ = exports;627 _ = exports;
619}628}
620pub fn deinit(self: *Plan9) void {629pub fn deinit(self: *Plan9) void {
...@@ -709,14 +718,18 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {...@@ -709,14 +718,18 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
709 });718 });
710 }719 }
711 }720 }
721
722 const mod = self.base.options.module.?;
723
712 // write the data symbols724 // write the data symbols
713 {725 {
714 var it = self.data_decl_table.iterator();726 var it = self.data_decl_table.iterator();
715 while (it.next()) |entry| {727 while (it.next()) |entry| {
716 const decl = entry.key_ptr.*;728 const decl_index = entry.key_ptr.*;
729 const decl = mod.declPtr(decl_index);
717 const sym = self.syms.items[decl.link.plan9.sym_index.?];730 const sym = self.syms.items[decl.link.plan9.sym_index.?];
718 try self.writeSym(writer, sym);731 try self.writeSym(writer, sym);
719 if (self.base.options.module.?.decl_exports.get(decl)) |exports| {732 if (self.base.options.module.?.decl_exports.get(decl_index)) |exports| {
720 for (exports) |e| {733 for (exports) |e| {
721 try self.writeSym(writer, self.syms.items[e.link.plan9.?]);734 try self.writeSym(writer, self.syms.items[e.link.plan9.?]);
722 }735 }
...@@ -737,10 +750,11 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {...@@ -737,10 +750,11 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
737 // write all the decls come from the file of the z symbol750 // write all the decls come from the file of the z symbol
738 var submap_it = symidx_and_submap.functions.iterator();751 var submap_it = symidx_and_submap.functions.iterator();
739 while (submap_it.next()) |entry| {752 while (submap_it.next()) |entry| {
740 const decl = entry.key_ptr.*;753 const decl_index = entry.key_ptr.*;
754 const decl = mod.declPtr(decl_index);
741 const sym = self.syms.items[decl.link.plan9.sym_index.?];755 const sym = self.syms.items[decl.link.plan9.sym_index.?];
742 try self.writeSym(writer, sym);756 try self.writeSym(writer, sym);
743 if (self.base.options.module.?.decl_exports.get(decl)) |exports| {757 if (self.base.options.module.?.decl_exports.get(decl_index)) |exports| {
744 for (exports) |e| {758 for (exports) |e| {
745 const s = self.syms.items[e.link.plan9.?];759 const s = self.syms.items[e.link.plan9.?];
746 if (mem.eql(u8, s.name, "_start"))760 if (mem.eql(u8, s.name, "_start"))
...@@ -754,12 +768,18 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {...@@ -754,12 +768,18 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
754}768}
755769
756/// this will be removed, moved to updateFinish770/// this will be removed, moved to updateFinish
757pub fn allocateDeclIndexes(self: *Plan9, decl: *Module.Decl) !void {771pub fn allocateDeclIndexes(self: *Plan9, decl_index: Module.Decl.Index) !void {
758 _ = self;772 _ = self;
759 _ = decl;773 _ = decl_index;
760}774}
761pub fn getDeclVAddr(self: *Plan9, decl: *const Module.Decl, reloc_info: link.File.RelocInfo) !u64 {775pub fn getDeclVAddr(
776 self: *Plan9,
777 decl_index: Module.Decl.Index,
778 reloc_info: link.File.RelocInfo,
779) !u64 {
762 _ = reloc_info;780 _ = reloc_info;
781 const mod = self.base.options.module.?;
782 const decl = mod.declPtr(decl_index);
763 if (decl.ty.zigTypeTag() == .Fn) {783 if (decl.ty.zigTypeTag() == .Fn) {
764 var start = self.bases.text;784 var start = self.bases.text;
765 var it_file = self.fn_decl_table.iterator();785 var it_file = self.fn_decl_table.iterator();
...@@ -767,7 +787,7 @@ pub fn getDeclVAddr(self: *Plan9, decl: *const Module.Decl, reloc_info: link.Fil...@@ -767,7 +787,7 @@ pub fn getDeclVAddr(self: *Plan9, decl: *const Module.Decl, reloc_info: link.Fil
767 var symidx_and_submap = fentry.value_ptr;787 var symidx_and_submap = fentry.value_ptr;
768 var submap_it = symidx_and_submap.functions.iterator();788 var submap_it = symidx_and_submap.functions.iterator();
769 while (submap_it.next()) |entry| {789 while (submap_it.next()) |entry| {
770 if (entry.key_ptr.* == decl) return start;790 if (entry.key_ptr.* == decl_index) return start;
771 start += entry.value_ptr.code.len;791 start += entry.value_ptr.code.len;
772 }792 }
773 }793 }
...@@ -776,7 +796,7 @@ pub fn getDeclVAddr(self: *Plan9, decl: *const Module.Decl, reloc_info: link.Fil...@@ -776,7 +796,7 @@ pub fn getDeclVAddr(self: *Plan9, decl: *const Module.Decl, reloc_info: link.Fil
776 var start = self.bases.data + self.got_len * if (!self.sixtyfour_bit) @as(u32, 4) else 8;796 var start = self.bases.data + self.got_len * if (!self.sixtyfour_bit) @as(u32, 4) else 8;
777 var it = self.data_decl_table.iterator();797 var it = self.data_decl_table.iterator();
778 while (it.next()) |kv| {798 while (it.next()) |kv| {
779 if (decl == kv.key_ptr.*) return start;799 if (decl_index == kv.key_ptr.*) return start;
780 start += kv.value_ptr.len;800 start += kv.value_ptr.len;
781 }801 }
782 unreachable;802 unreachable;
src/link/SpirV.zig+14-10
...@@ -54,7 +54,7 @@ base: link.File,...@@ -54,7 +54,7 @@ base: link.File,
54/// This linker backend does not try to incrementally link output SPIR-V code.54/// This linker backend does not try to incrementally link output SPIR-V code.
55/// Instead, it tracks all declarations in this table, and iterates over it55/// Instead, it tracks all declarations in this table, and iterates over it
56/// in the flush function.56/// in the flush function.
57decl_table: std.AutoArrayHashMapUnmanaged(*Module.Decl, DeclGenContext) = .{},57decl_table: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclGenContext) = .{},
5858
59const DeclGenContext = struct {59const DeclGenContext = struct {
60 air: Air,60 air: Air,
...@@ -145,29 +145,31 @@ pub fn updateFunc(self: *SpirV, module: *Module, func: *Module.Fn, air: Air, liv...@@ -145,29 +145,31 @@ pub fn updateFunc(self: *SpirV, module: *Module, func: *Module.Fn, air: Air, liv
145 };145 };
146}146}
147147
148pub fn updateDecl(self: *SpirV, module: *Module, decl: *Module.Decl) !void {148pub fn updateDecl(self: *SpirV, module: *Module, decl_index: Module.Decl.Index) !void {
149 if (build_options.skip_non_native) {149 if (build_options.skip_non_native) {
150 @panic("Attempted to compile for architecture that was disabled by build configuration");150 @panic("Attempted to compile for architecture that was disabled by build configuration");
151 }151 }
152 _ = module;152 _ = module;
153 // Keep track of all decls so we can iterate over them on flush().153 // Keep track of all decls so we can iterate over them on flush().
154 _ = try self.decl_table.getOrPut(self.base.allocator, decl);154 _ = try self.decl_table.getOrPut(self.base.allocator, decl_index);
155}155}
156156
157pub fn updateDeclExports(157pub fn updateDeclExports(
158 self: *SpirV,158 self: *SpirV,
159 module: *Module,159 module: *Module,
160 decl: *const Module.Decl,160 decl_index: Module.Decl.Index,
161 exports: []const *Module.Export,161 exports: []const *Module.Export,
162) !void {162) !void {
163 _ = self;163 _ = self;
164 _ = module;164 _ = module;
165 _ = decl;165 _ = decl_index;
166 _ = exports;166 _ = exports;
167}167}
168168
169pub fn freeDecl(self: *SpirV, decl: *Module.Decl) void {169pub fn freeDecl(self: *SpirV, decl_index: Module.Decl.Index) void {
170 const index = self.decl_table.getIndex(decl).?;170 const index = self.decl_table.getIndex(decl_index).?;
171 const module = self.base.options.module.?;
172 const decl = module.declPtr(decl_index);
171 if (decl.val.tag() == .function) {173 if (decl.val.tag() == .function) {
172 self.decl_table.values()[index].deinit(self.base.allocator);174 self.decl_table.values()[index].deinit(self.base.allocator);
173 }175 }
...@@ -208,7 +210,8 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No...@@ -208,7 +210,8 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No
208 // TODO: We're allocating an ID unconditionally now, are there210 // TODO: We're allocating an ID unconditionally now, are there
209 // declarations which don't generate a result?211 // declarations which don't generate a result?
210 // TODO: fn_link is used here, but thats probably not the right field. It will work anyway though.212 // TODO: fn_link is used here, but thats probably not the right field. It will work anyway though.
211 for (self.decl_table.keys()) |decl| {213 for (self.decl_table.keys()) |decl_index| {
214 const decl = module.declPtr(decl_index);
212 if (decl.has_tv) {215 if (decl.has_tv) {
213 decl.fn_link.spirv.id = spv.allocId();216 decl.fn_link.spirv.id = spv.allocId();
214 }217 }
...@@ -220,7 +223,8 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No...@@ -220,7 +223,8 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No
220223
221 var it = self.decl_table.iterator();224 var it = self.decl_table.iterator();
222 while (it.next()) |entry| {225 while (it.next()) |entry| {
223 const decl = entry.key_ptr.*;226 const decl_index = entry.key_ptr.*;
227 const decl = module.declPtr(decl_index);
224 if (!decl.has_tv) continue;228 if (!decl.has_tv) continue;
225229
226 const air = entry.value_ptr.air;230 const air = entry.value_ptr.air;
...@@ -228,7 +232,7 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No...@@ -228,7 +232,7 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No
228232
229 // Note, if `decl` is not a function, air/liveness may be undefined.233 // Note, if `decl` is not a function, air/liveness may be undefined.
230 if (try decl_gen.gen(decl, air, liveness)) |msg| {234 if (try decl_gen.gen(decl, air, liveness)) |msg| {
231 try module.failed_decls.put(module.gpa, decl, msg);235 try module.failed_decls.put(module.gpa, decl_index, msg);
232 return; // TODO: Attempt to generate more decls?236 return; // TODO: Attempt to generate more decls?
233 }237 }
234 }238 }
src/link/Wasm.zig+70-47
...@@ -48,7 +48,7 @@ host_name: []const u8 = "env",...@@ -48,7 +48,7 @@ host_name: []const u8 = "env",
48/// List of all `Decl` that are currently alive.48/// List of all `Decl` that are currently alive.
49/// This is ment for bookkeeping so we can safely cleanup all codegen memory49/// This is ment for bookkeeping so we can safely cleanup all codegen memory
50/// when calling `deinit`50/// when calling `deinit`
51decls: std.AutoHashMapUnmanaged(*Module.Decl, void) = .{},51decls: std.AutoHashMapUnmanaged(Module.Decl.Index, void) = .{},
52/// List of all symbols generated by Zig code.52/// List of all symbols generated by Zig code.
53symbols: std.ArrayListUnmanaged(Symbol) = .{},53symbols: std.ArrayListUnmanaged(Symbol) = .{},
54/// List of symbol indexes which are free to be used.54/// List of symbol indexes which are free to be used.
...@@ -429,9 +429,14 @@ pub fn deinit(self: *Wasm) void {...@@ -429,9 +429,14 @@ pub fn deinit(self: *Wasm) void {
429 if (self.llvm_object) |llvm_object| llvm_object.destroy(gpa);429 if (self.llvm_object) |llvm_object| llvm_object.destroy(gpa);
430 }430 }
431431
432 var decl_it = self.decls.keyIterator();432 if (self.base.options.module) |mod| {
433 while (decl_it.next()) |decl_ptr| {433 var decl_it = self.decls.keyIterator();
434 decl_ptr.*.link.wasm.deinit(gpa);434 while (decl_it.next()) |decl_index_ptr| {
435 const decl = mod.declPtr(decl_index_ptr.*);
436 decl.link.wasm.deinit(gpa);
437 }
438 } else {
439 assert(self.decls.count() == 0);
435 }440 }
436441
437 for (self.func_types.items) |*func_type| {442 for (self.func_types.items) |*func_type| {
...@@ -476,12 +481,13 @@ pub fn deinit(self: *Wasm) void {...@@ -476,12 +481,13 @@ pub fn deinit(self: *Wasm) void {
476 self.string_table.deinit(gpa);481 self.string_table.deinit(gpa);
477}482}
478483
479pub fn allocateDeclIndexes(self: *Wasm, decl: *Module.Decl) !void {484pub fn allocateDeclIndexes(self: *Wasm, decl_index: Module.Decl.Index) !void {
480 if (self.llvm_object) |_| return;485 if (self.llvm_object) |_| return;
486 const decl = self.base.options.module.?.declPtr(decl_index);
481 if (decl.link.wasm.sym_index != 0) return;487 if (decl.link.wasm.sym_index != 0) return;
482488
483 try self.symbols.ensureUnusedCapacity(self.base.allocator, 1);489 try self.symbols.ensureUnusedCapacity(self.base.allocator, 1);
484 try self.decls.putNoClobber(self.base.allocator, decl, {});490 try self.decls.putNoClobber(self.base.allocator, decl_index, {});
485491
486 const atom = &decl.link.wasm;492 const atom = &decl.link.wasm;
487493
...@@ -502,14 +508,15 @@ pub fn allocateDeclIndexes(self: *Wasm, decl: *Module.Decl) !void {...@@ -502,14 +508,15 @@ pub fn allocateDeclIndexes(self: *Wasm, decl: *Module.Decl) !void {
502 try self.symbol_atom.putNoClobber(self.base.allocator, atom.symbolLoc(), atom);508 try self.symbol_atom.putNoClobber(self.base.allocator, atom.symbolLoc(), atom);
503}509}
504510
505pub fn updateFunc(self: *Wasm, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {511pub fn updateFunc(self: *Wasm, mod: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {
506 if (build_options.skip_non_native and builtin.object_format != .wasm) {512 if (build_options.skip_non_native and builtin.object_format != .wasm) {
507 @panic("Attempted to compile for object format that was disabled by build configuration");513 @panic("Attempted to compile for object format that was disabled by build configuration");
508 }514 }
509 if (build_options.have_llvm) {515 if (build_options.have_llvm) {
510 if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(module, func, air, liveness);516 if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(mod, func, air, liveness);
511 }517 }
512 const decl = func.owner_decl;518 const decl_index = func.owner_decl;
519 const decl = mod.declPtr(decl_index);
513 assert(decl.link.wasm.sym_index != 0); // Must call allocateDeclIndexes()520 assert(decl.link.wasm.sym_index != 0); // Must call allocateDeclIndexes()
514521
515 decl.link.wasm.clear();522 decl.link.wasm.clear();
...@@ -530,7 +537,7 @@ pub fn updateFunc(self: *Wasm, module: *Module, func: *Module.Fn, air: Air, live...@@ -530,7 +537,7 @@ pub fn updateFunc(self: *Wasm, module: *Module, func: *Module.Fn, air: Air, live
530 .appended => code_writer.items,537 .appended => code_writer.items,
531 .fail => |em| {538 .fail => |em| {
532 decl.analysis = .codegen_failure;539 decl.analysis = .codegen_failure;
533 try module.failed_decls.put(module.gpa, decl, em);540 try mod.failed_decls.put(mod.gpa, decl_index, em);
534 return;541 return;
535 },542 },
536 };543 };
...@@ -540,14 +547,15 @@ pub fn updateFunc(self: *Wasm, module: *Module, func: *Module.Fn, air: Air, live...@@ -540,14 +547,15 @@ pub fn updateFunc(self: *Wasm, module: *Module, func: *Module.Fn, air: Air, live
540547
541// Generate code for the Decl, storing it in memory to be later written to548// Generate code for the Decl, storing it in memory to be later written to
542// the file on flush().549// the file on flush().
543pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void {550pub fn updateDecl(self: *Wasm, mod: *Module, decl_index: Module.Decl.Index) !void {
544 if (build_options.skip_non_native and builtin.object_format != .wasm) {551 if (build_options.skip_non_native and builtin.object_format != .wasm) {
545 @panic("Attempted to compile for object format that was disabled by build configuration");552 @panic("Attempted to compile for object format that was disabled by build configuration");
546 }553 }
547 if (build_options.have_llvm) {554 if (build_options.have_llvm) {
548 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(module, decl);555 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(mod, decl_index);
549 }556 }
550557
558 const decl = mod.declPtr(decl_index);
551 assert(decl.link.wasm.sym_index != 0); // Must call allocateDeclIndexes()559 assert(decl.link.wasm.sym_index != 0); // Must call allocateDeclIndexes()
552560
553 decl.link.wasm.clear();561 decl.link.wasm.clear();
...@@ -580,7 +588,7 @@ pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void {...@@ -580,7 +588,7 @@ pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void {
580 .appended => code_writer.items,588 .appended => code_writer.items,
581 .fail => |em| {589 .fail => |em| {
582 decl.analysis = .codegen_failure;590 decl.analysis = .codegen_failure;
583 try module.failed_decls.put(module.gpa, decl, em);591 try mod.failed_decls.put(mod.gpa, decl_index, em);
584 return;592 return;
585 },593 },
586 };594 };
...@@ -590,12 +598,13 @@ pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void {...@@ -590,12 +598,13 @@ pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void {
590598
591fn finishUpdateDecl(self: *Wasm, decl: *Module.Decl, code: []const u8) !void {599fn finishUpdateDecl(self: *Wasm, decl: *Module.Decl, code: []const u8) !void {
592 if (code.len == 0) return;600 if (code.len == 0) return;
601 const mod = self.base.options.module.?;
593 const atom: *Atom = &decl.link.wasm;602 const atom: *Atom = &decl.link.wasm;
594 atom.size = @intCast(u32, code.len);603 atom.size = @intCast(u32, code.len);
595 atom.alignment = decl.ty.abiAlignment(self.base.options.target);604 atom.alignment = decl.ty.abiAlignment(self.base.options.target);
596 const symbol = &self.symbols.items[atom.sym_index];605 const symbol = &self.symbols.items[atom.sym_index];
597606
598 const full_name = try decl.getFullyQualifiedName(self.base.allocator);607 const full_name = try decl.getFullyQualifiedName(mod);
599 defer self.base.allocator.free(full_name);608 defer self.base.allocator.free(full_name);
600 symbol.name = try self.string_table.put(self.base.allocator, full_name);609 symbol.name = try self.string_table.put(self.base.allocator, full_name);
601 try atom.code.appendSlice(self.base.allocator, code);610 try atom.code.appendSlice(self.base.allocator, code);
...@@ -606,12 +615,15 @@ fn finishUpdateDecl(self: *Wasm, decl: *Module.Decl, code: []const u8) !void {...@@ -606,12 +615,15 @@ fn finishUpdateDecl(self: *Wasm, decl: *Module.Decl, code: []const u8) !void {
606/// Lowers a constant typed value to a local symbol and atom.615/// Lowers a constant typed value to a local symbol and atom.
607/// Returns the symbol index of the local616/// Returns the symbol index of the local
608/// The given `decl` is the parent decl whom owns the constant.617/// The given `decl` is the parent decl whom owns the constant.
609pub fn lowerUnnamedConst(self: *Wasm, decl: *Module.Decl, tv: TypedValue) !u32 {618pub fn lowerUnnamedConst(self: *Wasm, tv: TypedValue, decl_index: Module.Decl.Index) !u32 {
610 assert(tv.ty.zigTypeTag() != .Fn); // cannot create local symbols for functions619 assert(tv.ty.zigTypeTag() != .Fn); // cannot create local symbols for functions
611620
621 const mod = self.base.options.module.?;
622 const decl = mod.declPtr(decl_index);
623
612 // Create and initialize a new local symbol and atom624 // Create and initialize a new local symbol and atom
613 const local_index = decl.link.wasm.locals.items.len;625 const local_index = decl.link.wasm.locals.items.len;
614 const fqdn = try decl.getFullyQualifiedName(self.base.allocator);626 const fqdn = try decl.getFullyQualifiedName(mod);
615 defer self.base.allocator.free(fqdn);627 defer self.base.allocator.free(fqdn);
616 const name = try std.fmt.allocPrintZ(self.base.allocator, "__unnamed_{s}_{d}", .{ fqdn, local_index });628 const name = try std.fmt.allocPrintZ(self.base.allocator, "__unnamed_{s}_{d}", .{ fqdn, local_index });
617 defer self.base.allocator.free(name);629 defer self.base.allocator.free(name);
...@@ -641,7 +653,6 @@ pub fn lowerUnnamedConst(self: *Wasm, decl: *Module.Decl, tv: TypedValue) !u32 {...@@ -641,7 +653,6 @@ pub fn lowerUnnamedConst(self: *Wasm, decl: *Module.Decl, tv: TypedValue) !u32 {
641 var value_bytes = std.ArrayList(u8).init(self.base.allocator);653 var value_bytes = std.ArrayList(u8).init(self.base.allocator);
642 defer value_bytes.deinit();654 defer value_bytes.deinit();
643655
644 const module = self.base.options.module.?;
645 const result = try codegen.generateSymbol(656 const result = try codegen.generateSymbol(
646 &self.base,657 &self.base,
647 decl.srcLoc(),658 decl.srcLoc(),
...@@ -658,7 +669,7 @@ pub fn lowerUnnamedConst(self: *Wasm, decl: *Module.Decl, tv: TypedValue) !u32 {...@@ -658,7 +669,7 @@ pub fn lowerUnnamedConst(self: *Wasm, decl: *Module.Decl, tv: TypedValue) !u32 {
658 .appended => value_bytes.items,669 .appended => value_bytes.items,
659 .fail => |em| {670 .fail => |em| {
660 decl.analysis = .codegen_failure;671 decl.analysis = .codegen_failure;
661 try module.failed_decls.put(module.gpa, decl, em);672 try mod.failed_decls.put(mod.gpa, decl_index, em);
662 return error.AnalysisFail;673 return error.AnalysisFail;
663 },674 },
664 };675 };
...@@ -672,9 +683,11 @@ pub fn lowerUnnamedConst(self: *Wasm, decl: *Module.Decl, tv: TypedValue) !u32 {...@@ -672,9 +683,11 @@ pub fn lowerUnnamedConst(self: *Wasm, decl: *Module.Decl, tv: TypedValue) !u32 {
672/// Returns the given pointer address683/// Returns the given pointer address
673pub fn getDeclVAddr(684pub fn getDeclVAddr(
674 self: *Wasm,685 self: *Wasm,
675 decl: *const Module.Decl,686 decl_index: Module.Decl.Index,
676 reloc_info: link.File.RelocInfo,687 reloc_info: link.File.RelocInfo,
677) !u64 {688) !u64 {
689 const mod = self.base.options.module.?;
690 const decl = mod.declPtr(decl_index);
678 const target_symbol_index = decl.link.wasm.sym_index;691 const target_symbol_index = decl.link.wasm.sym_index;
679 assert(target_symbol_index != 0);692 assert(target_symbol_index != 0);
680 assert(reloc_info.parent_atom_index != 0);693 assert(reloc_info.parent_atom_index != 0);
...@@ -722,21 +735,23 @@ pub fn deleteExport(self: *Wasm, exp: Export) void {...@@ -722,21 +735,23 @@ pub fn deleteExport(self: *Wasm, exp: Export) void {
722735
723pub fn updateDeclExports(736pub fn updateDeclExports(
724 self: *Wasm,737 self: *Wasm,
725 module: *Module,738 mod: *Module,
726 decl: *const Module.Decl,739 decl_index: Module.Decl.Index,
727 exports: []const *Module.Export,740 exports: []const *Module.Export,
728) !void {741) !void {
729 if (build_options.skip_non_native and builtin.object_format != .wasm) {742 if (build_options.skip_non_native and builtin.object_format != .wasm) {
730 @panic("Attempted to compile for object format that was disabled by build configuration");743 @panic("Attempted to compile for object format that was disabled by build configuration");
731 }744 }
732 if (build_options.have_llvm) {745 if (build_options.have_llvm) {
733 if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(module, decl, exports);746 if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(mod, decl_index, exports);
734 }747 }
735748
749 const decl = mod.declPtr(decl_index);
750
736 for (exports) |exp| {751 for (exports) |exp| {
737 if (exp.options.section) |section| {752 if (exp.options.section) |section| {
738 try module.failed_exports.putNoClobber(module.gpa, exp, try Module.ErrorMsg.create(753 try mod.failed_exports.putNoClobber(mod.gpa, exp, try Module.ErrorMsg.create(
739 module.gpa,754 mod.gpa,
740 decl.srcLoc(),755 decl.srcLoc(),
741 "Unimplemented: ExportOptions.section '{s}'",756 "Unimplemented: ExportOptions.section '{s}'",
742 .{section},757 .{section},
...@@ -754,8 +769,8 @@ pub fn updateDeclExports(...@@ -754,8 +769,8 @@ pub fn updateDeclExports(
754 // are strong symbols, we have a linker error.769 // are strong symbols, we have a linker error.
755 // In the other case we replace one with the other.770 // In the other case we replace one with the other.
756 if (!exp_is_weak and !existing_sym.isWeak()) {771 if (!exp_is_weak and !existing_sym.isWeak()) {
757 try module.failed_exports.put(module.gpa, exp, try Module.ErrorMsg.create(772 try mod.failed_exports.put(mod.gpa, exp, try Module.ErrorMsg.create(
758 module.gpa,773 mod.gpa,
759 decl.srcLoc(),774 decl.srcLoc(),
760 \\LinkError: symbol '{s}' defined multiple times775 \\LinkError: symbol '{s}' defined multiple times
761 \\ first definition in '{s}'776 \\ first definition in '{s}'
...@@ -773,8 +788,9 @@ pub fn updateDeclExports(...@@ -773,8 +788,9 @@ pub fn updateDeclExports(
773 }788 }
774 }789 }
775790
776 const sym_index = exp.exported_decl.link.wasm.sym_index;791 const exported_decl = mod.declPtr(exp.exported_decl);
777 const sym_loc = exp.exported_decl.link.wasm.symbolLoc();792 const sym_index = exported_decl.link.wasm.sym_index;
793 const sym_loc = exported_decl.link.wasm.symbolLoc();
778 const symbol = sym_loc.getSymbol(self);794 const symbol = sym_loc.getSymbol(self);
779 switch (exp.options.linkage) {795 switch (exp.options.linkage) {
780 .Internal => {796 .Internal => {
...@@ -786,8 +802,8 @@ pub fn updateDeclExports(...@@ -786,8 +802,8 @@ pub fn updateDeclExports(
786 },802 },
787 .Strong => {}, // symbols are strong by default803 .Strong => {}, // symbols are strong by default
788 .LinkOnce => {804 .LinkOnce => {
789 try module.failed_exports.putNoClobber(module.gpa, exp, try Module.ErrorMsg.create(805 try mod.failed_exports.putNoClobber(mod.gpa, exp, try Module.ErrorMsg.create(
790 module.gpa,806 mod.gpa,
791 decl.srcLoc(),807 decl.srcLoc(),
792 "Unimplemented: LinkOnce",808 "Unimplemented: LinkOnce",
793 .{},809 .{},
...@@ -813,13 +829,15 @@ pub fn updateDeclExports(...@@ -813,13 +829,15 @@ pub fn updateDeclExports(
813 }829 }
814}830}
815831
816pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void {832pub fn freeDecl(self: *Wasm, decl_index: Module.Decl.Index) void {
817 if (build_options.have_llvm) {833 if (build_options.have_llvm) {
818 if (self.llvm_object) |llvm_object| return llvm_object.freeDecl(decl);834 if (self.llvm_object) |llvm_object| return llvm_object.freeDecl(decl_index);
819 }835 }
836 const mod = self.base.options.module.?;
837 const decl = mod.declPtr(decl_index);
820 const atom = &decl.link.wasm;838 const atom = &decl.link.wasm;
821 self.symbols_free_list.append(self.base.allocator, atom.sym_index) catch {};839 self.symbols_free_list.append(self.base.allocator, atom.sym_index) catch {};
822 _ = self.decls.remove(decl);840 _ = self.decls.remove(decl_index);
823 self.symbols.items[atom.sym_index].tag = .dead;841 self.symbols.items[atom.sym_index].tag = .dead;
824 for (atom.locals.items) |local_atom| {842 for (atom.locals.items) |local_atom| {
825 const local_symbol = &self.symbols.items[local_atom.sym_index];843 const local_symbol = &self.symbols.items[local_atom.sym_index];
...@@ -1414,8 +1432,8 @@ fn populateErrorNameTable(self: *Wasm) !void {...@@ -1414,8 +1432,8 @@ fn populateErrorNameTable(self: *Wasm) !void {
14141432
1415 // Addend for each relocation to the table1433 // Addend for each relocation to the table
1416 var addend: u32 = 0;1434 var addend: u32 = 0;
1417 const module = self.base.options.module.?;1435 const mod = self.base.options.module.?;
1418 for (module.error_name_list.items) |error_name| {1436 for (mod.error_name_list.items) |error_name| {
1419 const len = @intCast(u32, error_name.len + 1); // names are 0-termianted1437 const len = @intCast(u32, error_name.len + 1); // names are 0-termianted
14201438
1421 const slice_ty = Type.initTag(.const_slice_u8_sentinel_0);1439 const slice_ty = Type.initTag(.const_slice_u8_sentinel_0);
...@@ -1456,9 +1474,11 @@ fn resetState(self: *Wasm) void {...@@ -1456,9 +1474,11 @@ fn resetState(self: *Wasm) void {
1456 for (self.segment_info.items) |*segment_info| {1474 for (self.segment_info.items) |*segment_info| {
1457 self.base.allocator.free(segment_info.name);1475 self.base.allocator.free(segment_info.name);
1458 }1476 }
1477 const mod = self.base.options.module.?;
1459 var decl_it = self.decls.keyIterator();1478 var decl_it = self.decls.keyIterator();
1460 while (decl_it.next()) |decl| {1479 while (decl_it.next()) |decl_index_ptr| {
1461 const atom = &decl.*.link.wasm;1480 const decl = mod.declPtr(decl_index_ptr.*);
1481 const atom = &decl.link.wasm;
1462 atom.next = null;1482 atom.next = null;
1463 atom.prev = null;1483 atom.prev = null;
14641484
...@@ -1546,12 +1566,14 @@ pub fn flushModule(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -1546,12 +1566,14 @@ pub fn flushModule(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
1546 defer self.resetState();1566 defer self.resetState();
1547 try self.setupStart();1567 try self.setupStart();
1548 try self.setupImports();1568 try self.setupImports();
1569 const mod = self.base.options.module.?;
1549 var decl_it = self.decls.keyIterator();1570 var decl_it = self.decls.keyIterator();
1550 while (decl_it.next()) |decl| {1571 while (decl_it.next()) |decl_index_ptr| {
1551 if (decl.*.isExtern()) continue;1572 const decl = mod.declPtr(decl_index_ptr.*);
1573 if (decl.isExtern()) continue;
1552 const atom = &decl.*.link.wasm;1574 const atom = &decl.*.link.wasm;
1553 if (decl.*.ty.zigTypeTag() == .Fn) {1575 if (decl.ty.zigTypeTag() == .Fn) {
1554 try self.parseAtom(atom, .{ .function = decl.*.fn_link.wasm });1576 try self.parseAtom(atom, .{ .function = decl.fn_link.wasm });
1555 } else {1577 } else {
1556 try self.parseAtom(atom, .data);1578 try self.parseAtom(atom, .data);
1557 }1579 }
...@@ -2045,7 +2067,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !...@@ -2045,7 +2067,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
20452067
2046 // If there is no Zig code to compile, then we should skip flushing the output file because it2068 // If there is no Zig code to compile, then we should skip flushing the output file because it
2047 // will not be part of the linker line anyway.2069 // will not be part of the linker line anyway.
2048 const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: {2070 const module_obj_path: ?[]const u8 = if (self.base.options.module) |mod| blk: {
2049 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;2071 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
2050 if (use_stage1) {2072 if (use_stage1) {
2051 const obj_basename = try std.zig.binNameAlloc(arena, .{2073 const obj_basename = try std.zig.binNameAlloc(arena, .{
...@@ -2054,7 +2076,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !...@@ -2054,7 +2076,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
2054 .output_mode = .Obj,2076 .output_mode = .Obj,
2055 });2077 });
2056 switch (self.base.options.cache_mode) {2078 switch (self.base.options.cache_mode) {
2057 .incremental => break :blk try module.zig_cache_artifact_directory.join(2079 .incremental => break :blk try mod.zig_cache_artifact_directory.join(
2058 arena,2080 arena,
2059 &[_][]const u8{obj_basename},2081 &[_][]const u8{obj_basename},
2060 ),2082 ),
...@@ -2253,7 +2275,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !...@@ -2253,7 +2275,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
2253 }2275 }
22542276
2255 if (auto_export_symbols) {2277 if (auto_export_symbols) {
2256 if (self.base.options.module) |module| {2278 if (self.base.options.module) |mod| {
2257 // when we use stage1, we use the exports that stage1 provided us.2279 // when we use stage1, we use the exports that stage1 provided us.
2258 // For stage2, we can directly retrieve them from the module.2280 // For stage2, we can directly retrieve them from the module.
2259 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;2281 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
...@@ -2264,14 +2286,15 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !...@@ -2264,14 +2286,15 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
2264 } else {2286 } else {
2265 const skip_export_non_fn = target.os.tag == .wasi and2287 const skip_export_non_fn = target.os.tag == .wasi and
2266 self.base.options.wasi_exec_model == .command;2288 self.base.options.wasi_exec_model == .command;
2267 for (module.decl_exports.values()) |exports| {2289 for (mod.decl_exports.values()) |exports| {
2268 for (exports) |exprt| {2290 for (exports) |exprt| {
2269 if (skip_export_non_fn and exprt.exported_decl.ty.zigTypeTag() != .Fn) {2291 const exported_decl = mod.declPtr(exprt.exported_decl);
2292 if (skip_export_non_fn and exported_decl.ty.zigTypeTag() != .Fn) {
2270 // skip exporting symbols when we're building a WASI command2293 // skip exporting symbols when we're building a WASI command
2271 // and the symbol is not a function2294 // and the symbol is not a function
2272 continue;2295 continue;
2273 }2296 }
2274 const symbol_name = exprt.exported_decl.name;2297 const symbol_name = exported_decl.name;
2275 const arg = try std.fmt.allocPrint(arena, "--export={s}", .{symbol_name});2298 const arg = try std.fmt.allocPrint(arena, "--export={s}", .{symbol_name});
2276 try argv.append(arg);2299 try argv.append(arg);
2277 }2300 }
src/main.zig+4-4
...@@ -3892,7 +3892,7 @@ pub fn cmdFmt(gpa: Allocator, arena: Allocator, args: []const []const u8) !void...@@ -3892,7 +3892,7 @@ pub fn cmdFmt(gpa: Allocator, arena: Allocator, args: []const []const u8) !void
3892 .tree_loaded = true,3892 .tree_loaded = true,
3893 .zir = undefined,3893 .zir = undefined,
3894 .pkg = undefined,3894 .pkg = undefined,
3895 .root_decl = null,3895 .root_decl = .none,
3896 };3896 };
38973897
3898 file.pkg = try Package.create(gpa, null, file.sub_file_path);3898 file.pkg = try Package.create(gpa, null, file.sub_file_path);
...@@ -4098,7 +4098,7 @@ fn fmtPathFile(...@@ -4098,7 +4098,7 @@ fn fmtPathFile(
4098 .tree_loaded = true,4098 .tree_loaded = true,
4099 .zir = undefined,4099 .zir = undefined,
4100 .pkg = undefined,4100 .pkg = undefined,
4101 .root_decl = null,4101 .root_decl = .none,
4102 };4102 };
41034103
4104 file.pkg = try Package.create(fmt.gpa, null, file.sub_file_path);4104 file.pkg = try Package.create(fmt.gpa, null, file.sub_file_path);
...@@ -4757,7 +4757,7 @@ pub fn cmdAstCheck(...@@ -4757,7 +4757,7 @@ pub fn cmdAstCheck(
4757 .tree = undefined,4757 .tree = undefined,
4758 .zir = undefined,4758 .zir = undefined,
4759 .pkg = undefined,4759 .pkg = undefined,
4760 .root_decl = null,4760 .root_decl = .none,
4761 };4761 };
4762 if (zig_source_file) |file_name| {4762 if (zig_source_file) |file_name| {
4763 var f = fs.cwd().openFile(file_name, .{}) catch |err| {4763 var f = fs.cwd().openFile(file_name, .{}) catch |err| {
...@@ -4910,7 +4910,7 @@ pub fn cmdChangelist(...@@ -4910,7 +4910,7 @@ pub fn cmdChangelist(
4910 .tree = undefined,4910 .tree = undefined,
4911 .zir = undefined,4911 .zir = undefined,
4912 .pkg = undefined,4912 .pkg = undefined,
4913 .root_decl = null,4913 .root_decl = .none,
4914 };4914 };
49154915
4916 file.pkg = try Package.create(gpa, null, file.sub_file_path);4916 file.pkg = try Package.create(gpa, null, file.sub_file_path);
src/print_air.zig+7-4
...@@ -7,7 +7,7 @@ const Value = @import("value.zig").Value;...@@ -7,7 +7,7 @@ const Value = @import("value.zig").Value;
7const Air = @import("Air.zig");7const Air = @import("Air.zig");
8const Liveness = @import("Liveness.zig");8const Liveness = @import("Liveness.zig");
99
10pub fn dump(gpa: Allocator, air: Air, liveness: Liveness) void {10pub fn dump(module: *Module, air: Air, liveness: Liveness) void {
11 const instruction_bytes = air.instructions.len *11 const instruction_bytes = air.instructions.len *
12 // Here we don't use @sizeOf(Air.Inst.Data) because it would include12 // Here we don't use @sizeOf(Air.Inst.Data) because it would include
13 // the debug safety tag but we want to measure release size.13 // the debug safety tag but we want to measure release size.
...@@ -41,11 +41,12 @@ pub fn dump(gpa: Allocator, air: Air, liveness: Liveness) void {...@@ -41,11 +41,12 @@ pub fn dump(gpa: Allocator, air: Air, liveness: Liveness) void {
41 liveness.special.count(), fmtIntSizeBin(liveness_special_bytes),41 liveness.special.count(), fmtIntSizeBin(liveness_special_bytes),
42 });42 });
43 // zig fmt: on43 // zig fmt: on
44 var arena = std.heap.ArenaAllocator.init(gpa);44 var arena = std.heap.ArenaAllocator.init(module.gpa);
45 defer arena.deinit();45 defer arena.deinit();
4646
47 var writer: Writer = .{47 var writer: Writer = .{
48 .gpa = gpa,48 .module = module,
49 .gpa = module.gpa,
49 .arena = arena.allocator(),50 .arena = arena.allocator(),
50 .air = air,51 .air = air,
51 .liveness = liveness,52 .liveness = liveness,
...@@ -58,6 +59,7 @@ pub fn dump(gpa: Allocator, air: Air, liveness: Liveness) void {...@@ -58,6 +59,7 @@ pub fn dump(gpa: Allocator, air: Air, liveness: Liveness) void {
58}59}
5960
60const Writer = struct {61const Writer = struct {
62 module: *Module,
61 gpa: Allocator,63 gpa: Allocator,
62 arena: Allocator,64 arena: Allocator,
63 air: Air,65 air: Air,
...@@ -591,7 +593,8 @@ const Writer = struct {...@@ -591,7 +593,8 @@ const Writer = struct {
591 fn writeDbgInline(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {593 fn writeDbgInline(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
592 const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;594 const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
593 const function = w.air.values[ty_pl.payload].castTag(.function).?.data;595 const function = w.air.values[ty_pl.payload].castTag(.function).?.data;
594 try s.print("{s}", .{function.owner_decl.name});596 const owner_decl = w.module.declPtr(function.owner_decl);
597 try s.print("{s}", .{owner_decl.name});
595 }598 }
596599
597 fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {600 fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
src/type.zig+150-124
...@@ -521,7 +521,7 @@ pub const Type = extern union {...@@ -521,7 +521,7 @@ pub const Type = extern union {
521 }521 }
522 }522 }
523523
524 pub fn eql(a: Type, b: Type, target: Target) bool {524 pub fn eql(a: Type, b: Type, mod: *Module) bool {
525 // As a shortcut, if the small tags / addresses match, we're done.525 // As a shortcut, if the small tags / addresses match, we're done.
526 if (a.tag_if_small_enough == b.tag_if_small_enough) return true;526 if (a.tag_if_small_enough == b.tag_if_small_enough) return true;
527527
...@@ -637,7 +637,7 @@ pub const Type = extern union {...@@ -637,7 +637,7 @@ pub const Type = extern union {
637 const a_info = a.fnInfo();637 const a_info = a.fnInfo();
638 const b_info = b.fnInfo();638 const b_info = b.fnInfo();
639639
640 if (!eql(a_info.return_type, b_info.return_type, target))640 if (!eql(a_info.return_type, b_info.return_type, mod))
641 return false;641 return false;
642642
643 if (a_info.cc != b_info.cc)643 if (a_info.cc != b_info.cc)
...@@ -663,7 +663,7 @@ pub const Type = extern union {...@@ -663,7 +663,7 @@ pub const Type = extern union {
663 if (a_param_ty.tag() == .generic_poison) continue;663 if (a_param_ty.tag() == .generic_poison) continue;
664 if (b_param_ty.tag() == .generic_poison) continue;664 if (b_param_ty.tag() == .generic_poison) continue;
665665
666 if (!eql(a_param_ty, b_param_ty, target))666 if (!eql(a_param_ty, b_param_ty, mod))
667 return false;667 return false;
668 }668 }
669669
...@@ -681,13 +681,13 @@ pub const Type = extern union {...@@ -681,13 +681,13 @@ pub const Type = extern union {
681 if (a.arrayLen() != b.arrayLen())681 if (a.arrayLen() != b.arrayLen())
682 return false;682 return false;
683 const elem_ty = a.elemType();683 const elem_ty = a.elemType();
684 if (!elem_ty.eql(b.elemType(), target))684 if (!elem_ty.eql(b.elemType(), mod))
685 return false;685 return false;
686 const sentinel_a = a.sentinel();686 const sentinel_a = a.sentinel();
687 const sentinel_b = b.sentinel();687 const sentinel_b = b.sentinel();
688 if (sentinel_a) |sa| {688 if (sentinel_a) |sa| {
689 if (sentinel_b) |sb| {689 if (sentinel_b) |sb| {
690 return sa.eql(sb, elem_ty, target);690 return sa.eql(sb, elem_ty, mod);
691 } else {691 } else {
692 return false;692 return false;
693 }693 }
...@@ -718,7 +718,7 @@ pub const Type = extern union {...@@ -718,7 +718,7 @@ pub const Type = extern union {
718718
719 const info_a = a.ptrInfo().data;719 const info_a = a.ptrInfo().data;
720 const info_b = b.ptrInfo().data;720 const info_b = b.ptrInfo().data;
721 if (!info_a.pointee_type.eql(info_b.pointee_type, target))721 if (!info_a.pointee_type.eql(info_b.pointee_type, mod))
722 return false;722 return false;
723 if (info_a.@"align" != info_b.@"align")723 if (info_a.@"align" != info_b.@"align")
724 return false;724 return false;
...@@ -741,7 +741,7 @@ pub const Type = extern union {...@@ -741,7 +741,7 @@ pub const Type = extern union {
741 const sentinel_b = info_b.sentinel;741 const sentinel_b = info_b.sentinel;
742 if (sentinel_a) |sa| {742 if (sentinel_a) |sa| {
743 if (sentinel_b) |sb| {743 if (sentinel_b) |sb| {
744 if (!sa.eql(sb, info_a.pointee_type, target))744 if (!sa.eql(sb, info_a.pointee_type, mod))
745 return false;745 return false;
746 } else {746 } else {
747 return false;747 return false;
...@@ -762,7 +762,7 @@ pub const Type = extern union {...@@ -762,7 +762,7 @@ pub const Type = extern union {
762762
763 var buf_a: Payload.ElemType = undefined;763 var buf_a: Payload.ElemType = undefined;
764 var buf_b: Payload.ElemType = undefined;764 var buf_b: Payload.ElemType = undefined;
765 return a.optionalChild(&buf_a).eql(b.optionalChild(&buf_b), target);765 return a.optionalChild(&buf_a).eql(b.optionalChild(&buf_b), mod);
766 },766 },
767767
768 .anyerror_void_error_union, .error_union => {768 .anyerror_void_error_union, .error_union => {
...@@ -770,18 +770,18 @@ pub const Type = extern union {...@@ -770,18 +770,18 @@ pub const Type = extern union {
770770
771 const a_set = a.errorUnionSet();771 const a_set = a.errorUnionSet();
772 const b_set = b.errorUnionSet();772 const b_set = b.errorUnionSet();
773 if (!a_set.eql(b_set, target)) return false;773 if (!a_set.eql(b_set, mod)) return false;
774774
775 const a_payload = a.errorUnionPayload();775 const a_payload = a.errorUnionPayload();
776 const b_payload = b.errorUnionPayload();776 const b_payload = b.errorUnionPayload();
777 if (!a_payload.eql(b_payload, target)) return false;777 if (!a_payload.eql(b_payload, mod)) return false;
778778
779 return true;779 return true;
780 },780 },
781781
782 .anyframe_T => {782 .anyframe_T => {
783 if (b.zigTypeTag() != .AnyFrame) return false;783 if (b.zigTypeTag() != .AnyFrame) return false;
784 return a.childType().eql(b.childType(), target);784 return a.childType().eql(b.childType(), mod);
785 },785 },
786786
787 .empty_struct => {787 .empty_struct => {
...@@ -804,7 +804,7 @@ pub const Type = extern union {...@@ -804,7 +804,7 @@ pub const Type = extern union {
804804
805 for (a_tuple.types) |a_ty, i| {805 for (a_tuple.types) |a_ty, i| {
806 const b_ty = b_tuple.types[i];806 const b_ty = b_tuple.types[i];
807 if (!eql(a_ty, b_ty, target)) return false;807 if (!eql(a_ty, b_ty, mod)) return false;
808 }808 }
809809
810 for (a_tuple.values) |a_val, i| {810 for (a_tuple.values) |a_val, i| {
...@@ -820,7 +820,7 @@ pub const Type = extern union {...@@ -820,7 +820,7 @@ pub const Type = extern union {
820 if (b_val.tag() == .unreachable_value) {820 if (b_val.tag() == .unreachable_value) {
821 return false;821 return false;
822 } else {822 } else {
823 if (!Value.eql(a_val, b_val, ty, target)) return false;823 if (!Value.eql(a_val, b_val, ty, mod)) return false;
824 }824 }
825 }825 }
826 }826 }
...@@ -840,7 +840,7 @@ pub const Type = extern union {...@@ -840,7 +840,7 @@ pub const Type = extern union {
840840
841 for (a_struct_obj.types) |a_ty, i| {841 for (a_struct_obj.types) |a_ty, i| {
842 const b_ty = b_struct_obj.types[i];842 const b_ty = b_struct_obj.types[i];
843 if (!eql(a_ty, b_ty, target)) return false;843 if (!eql(a_ty, b_ty, mod)) return false;
844 }844 }
845845
846 for (a_struct_obj.values) |a_val, i| {846 for (a_struct_obj.values) |a_val, i| {
...@@ -856,7 +856,7 @@ pub const Type = extern union {...@@ -856,7 +856,7 @@ pub const Type = extern union {
856 if (b_val.tag() == .unreachable_value) {856 if (b_val.tag() == .unreachable_value) {
857 return false;857 return false;
858 } else {858 } else {
859 if (!Value.eql(a_val, b_val, ty, target)) return false;859 if (!Value.eql(a_val, b_val, ty, mod)) return false;
860 }860 }
861 }861 }
862 }862 }
...@@ -911,13 +911,13 @@ pub const Type = extern union {...@@ -911,13 +911,13 @@ pub const Type = extern union {
911 }911 }
912 }912 }
913913
914 pub fn hash(self: Type, target: Target) u64 {914 pub fn hash(self: Type, mod: *Module) u64 {
915 var hasher = std.hash.Wyhash.init(0);915 var hasher = std.hash.Wyhash.init(0);
916 self.hashWithHasher(&hasher, target);916 self.hashWithHasher(&hasher, mod);
917 return hasher.final();917 return hasher.final();
918 }918 }
919919
920 pub fn hashWithHasher(ty: Type, hasher: *std.hash.Wyhash, target: Target) void {920 pub fn hashWithHasher(ty: Type, hasher: *std.hash.Wyhash, mod: *Module) void {
921 switch (ty.tag()) {921 switch (ty.tag()) {
922 .generic_poison => unreachable,922 .generic_poison => unreachable,
923923
...@@ -1036,7 +1036,7 @@ pub const Type = extern union {...@@ -1036,7 +1036,7 @@ pub const Type = extern union {
1036 std.hash.autoHash(hasher, std.builtin.TypeId.Fn);1036 std.hash.autoHash(hasher, std.builtin.TypeId.Fn);
10371037
1038 const fn_info = ty.fnInfo();1038 const fn_info = ty.fnInfo();
1039 hashWithHasher(fn_info.return_type, hasher, target);1039 hashWithHasher(fn_info.return_type, hasher, mod);
1040 std.hash.autoHash(hasher, fn_info.alignment);1040 std.hash.autoHash(hasher, fn_info.alignment);
1041 std.hash.autoHash(hasher, fn_info.cc);1041 std.hash.autoHash(hasher, fn_info.cc);
1042 std.hash.autoHash(hasher, fn_info.is_var_args);1042 std.hash.autoHash(hasher, fn_info.is_var_args);
...@@ -1046,7 +1046,7 @@ pub const Type = extern union {...@@ -1046,7 +1046,7 @@ pub const Type = extern union {
1046 for (fn_info.param_types) |param_ty, i| {1046 for (fn_info.param_types) |param_ty, i| {
1047 std.hash.autoHash(hasher, fn_info.paramIsComptime(i));1047 std.hash.autoHash(hasher, fn_info.paramIsComptime(i));
1048 if (param_ty.tag() == .generic_poison) continue;1048 if (param_ty.tag() == .generic_poison) continue;
1049 hashWithHasher(param_ty, hasher, target);1049 hashWithHasher(param_ty, hasher, mod);
1050 }1050 }
1051 },1051 },
10521052
...@@ -1059,8 +1059,8 @@ pub const Type = extern union {...@@ -1059,8 +1059,8 @@ pub const Type = extern union {
10591059
1060 const elem_ty = ty.elemType();1060 const elem_ty = ty.elemType();
1061 std.hash.autoHash(hasher, ty.arrayLen());1061 std.hash.autoHash(hasher, ty.arrayLen());
1062 hashWithHasher(elem_ty, hasher, target);1062 hashWithHasher(elem_ty, hasher, mod);
1063 hashSentinel(ty.sentinel(), elem_ty, hasher, target);1063 hashSentinel(ty.sentinel(), elem_ty, hasher, mod);
1064 },1064 },
10651065
1066 .vector => {1066 .vector => {
...@@ -1068,7 +1068,7 @@ pub const Type = extern union {...@@ -1068,7 +1068,7 @@ pub const Type = extern union {
10681068
1069 const elem_ty = ty.elemType();1069 const elem_ty = ty.elemType();
1070 std.hash.autoHash(hasher, ty.vectorLen());1070 std.hash.autoHash(hasher, ty.vectorLen());
1071 hashWithHasher(elem_ty, hasher, target);1071 hashWithHasher(elem_ty, hasher, mod);
1072 },1072 },
10731073
1074 .single_const_pointer_to_comptime_int,1074 .single_const_pointer_to_comptime_int,
...@@ -1092,8 +1092,8 @@ pub const Type = extern union {...@@ -1092,8 +1092,8 @@ pub const Type = extern union {
1092 std.hash.autoHash(hasher, std.builtin.TypeId.Pointer);1092 std.hash.autoHash(hasher, std.builtin.TypeId.Pointer);
10931093
1094 const info = ty.ptrInfo().data;1094 const info = ty.ptrInfo().data;
1095 hashWithHasher(info.pointee_type, hasher, target);1095 hashWithHasher(info.pointee_type, hasher, mod);
1096 hashSentinel(info.sentinel, info.pointee_type, hasher, target);1096 hashSentinel(info.sentinel, info.pointee_type, hasher, mod);
1097 std.hash.autoHash(hasher, info.@"align");1097 std.hash.autoHash(hasher, info.@"align");
1098 std.hash.autoHash(hasher, info.@"addrspace");1098 std.hash.autoHash(hasher, info.@"addrspace");
1099 std.hash.autoHash(hasher, info.bit_offset);1099 std.hash.autoHash(hasher, info.bit_offset);
...@@ -1111,22 +1111,22 @@ pub const Type = extern union {...@@ -1111,22 +1111,22 @@ pub const Type = extern union {
1111 std.hash.autoHash(hasher, std.builtin.TypeId.Optional);1111 std.hash.autoHash(hasher, std.builtin.TypeId.Optional);
11121112
1113 var buf: Payload.ElemType = undefined;1113 var buf: Payload.ElemType = undefined;
1114 hashWithHasher(ty.optionalChild(&buf), hasher, target);1114 hashWithHasher(ty.optionalChild(&buf), hasher, mod);
1115 },1115 },
11161116
1117 .anyerror_void_error_union, .error_union => {1117 .anyerror_void_error_union, .error_union => {
1118 std.hash.autoHash(hasher, std.builtin.TypeId.ErrorUnion);1118 std.hash.autoHash(hasher, std.builtin.TypeId.ErrorUnion);
11191119
1120 const set_ty = ty.errorUnionSet();1120 const set_ty = ty.errorUnionSet();
1121 hashWithHasher(set_ty, hasher, target);1121 hashWithHasher(set_ty, hasher, mod);
11221122
1123 const payload_ty = ty.errorUnionPayload();1123 const payload_ty = ty.errorUnionPayload();
1124 hashWithHasher(payload_ty, hasher, target);1124 hashWithHasher(payload_ty, hasher, mod);
1125 },1125 },
11261126
1127 .anyframe_T => {1127 .anyframe_T => {
1128 std.hash.autoHash(hasher, std.builtin.TypeId.AnyFrame);1128 std.hash.autoHash(hasher, std.builtin.TypeId.AnyFrame);
1129 hashWithHasher(ty.childType(), hasher, target);1129 hashWithHasher(ty.childType(), hasher, mod);
1130 },1130 },
11311131
1132 .empty_struct => {1132 .empty_struct => {
...@@ -1145,10 +1145,10 @@ pub const Type = extern union {...@@ -1145,10 +1145,10 @@ pub const Type = extern union {
1145 std.hash.autoHash(hasher, tuple.types.len);1145 std.hash.autoHash(hasher, tuple.types.len);
11461146
1147 for (tuple.types) |field_ty, i| {1147 for (tuple.types) |field_ty, i| {
1148 hashWithHasher(field_ty, hasher, target);1148 hashWithHasher(field_ty, hasher, mod);
1149 const field_val = tuple.values[i];1149 const field_val = tuple.values[i];
1150 if (field_val.tag() == .unreachable_value) continue;1150 if (field_val.tag() == .unreachable_value) continue;
1151 field_val.hash(field_ty, hasher, target);1151 field_val.hash(field_ty, hasher, mod);
1152 }1152 }
1153 },1153 },
1154 .anon_struct => {1154 .anon_struct => {
...@@ -1160,9 +1160,9 @@ pub const Type = extern union {...@@ -1160,9 +1160,9 @@ pub const Type = extern union {
1160 const field_name = struct_obj.names[i];1160 const field_name = struct_obj.names[i];
1161 const field_val = struct_obj.values[i];1161 const field_val = struct_obj.values[i];
1162 hasher.update(field_name);1162 hasher.update(field_name);
1163 hashWithHasher(field_ty, hasher, target);1163 hashWithHasher(field_ty, hasher, mod);
1164 if (field_val.tag() == .unreachable_value) continue;1164 if (field_val.tag() == .unreachable_value) continue;
1165 field_val.hash(field_ty, hasher, target);1165 field_val.hash(field_ty, hasher, mod);
1166 }1166 }
1167 },1167 },
11681168
...@@ -1210,35 +1210,35 @@ pub const Type = extern union {...@@ -1210,35 +1210,35 @@ pub const Type = extern union {
1210 }1210 }
1211 }1211 }
12121212
1213 fn hashSentinel(opt_val: ?Value, ty: Type, hasher: *std.hash.Wyhash, target: Target) void {1213 fn hashSentinel(opt_val: ?Value, ty: Type, hasher: *std.hash.Wyhash, mod: *Module) void {
1214 if (opt_val) |s| {1214 if (opt_val) |s| {
1215 std.hash.autoHash(hasher, true);1215 std.hash.autoHash(hasher, true);
1216 s.hash(ty, hasher, target);1216 s.hash(ty, hasher, mod);
1217 } else {1217 } else {
1218 std.hash.autoHash(hasher, false);1218 std.hash.autoHash(hasher, false);
1219 }1219 }
1220 }1220 }
12211221
1222 pub const HashContext64 = struct {1222 pub const HashContext64 = struct {
1223 target: Target,1223 mod: *Module,
12241224
1225 pub fn hash(self: @This(), t: Type) u64 {1225 pub fn hash(self: @This(), t: Type) u64 {
1226 return t.hash(self.target);1226 return t.hash(self.mod);
1227 }1227 }
1228 pub fn eql(self: @This(), a: Type, b: Type) bool {1228 pub fn eql(self: @This(), a: Type, b: Type) bool {
1229 return a.eql(b, self.target);1229 return a.eql(b, self.mod);
1230 }1230 }
1231 };1231 };
12321232
1233 pub const HashContext32 = struct {1233 pub const HashContext32 = struct {
1234 target: Target,1234 mod: *Module,
12351235
1236 pub fn hash(self: @This(), t: Type) u32 {1236 pub fn hash(self: @This(), t: Type) u32 {
1237 return @truncate(u32, t.hash(self.target));1237 return @truncate(u32, t.hash(self.mod));
1238 }1238 }
1239 pub fn eql(self: @This(), a: Type, b: Type, b_index: usize) bool {1239 pub fn eql(self: @This(), a: Type, b: Type, b_index: usize) bool {
1240 _ = b_index;1240 _ = b_index;
1241 return a.eql(b, self.target);1241 return a.eql(b, self.mod);
1242 }1242 }
1243 };1243 };
12441244
...@@ -1483,16 +1483,16 @@ pub const Type = extern union {...@@ -1483,16 +1483,16 @@ pub const Type = extern union {
1483 @compileError("do not format types directly; use either ty.fmtDebug() or ty.fmt()");1483 @compileError("do not format types directly; use either ty.fmtDebug() or ty.fmt()");
1484 }1484 }
14851485
1486 pub fn fmt(ty: Type, target: Target) std.fmt.Formatter(format2) {1486 pub fn fmt(ty: Type, module: *Module) std.fmt.Formatter(format2) {
1487 return .{ .data = .{1487 return .{ .data = .{
1488 .ty = ty,1488 .ty = ty,
1489 .target = target,1489 .module = module,
1490 } };1490 } };
1491 }1491 }
14921492
1493 const FormatContext = struct {1493 const FormatContext = struct {
1494 ty: Type,1494 ty: Type,
1495 target: Target,1495 module: *Module,
1496 };1496 };
14971497
1498 fn format2(1498 fn format2(
...@@ -1503,7 +1503,7 @@ pub const Type = extern union {...@@ -1503,7 +1503,7 @@ pub const Type = extern union {
1503 ) !void {1503 ) !void {
1504 comptime assert(unused_format_string.len == 0);1504 comptime assert(unused_format_string.len == 0);
1505 _ = options;1505 _ = options;
1506 return print(ctx.ty, writer, ctx.target);1506 return print(ctx.ty, writer, ctx.module);
1507 }1507 }
15081508
1509 pub fn fmtDebug(ty: Type) std.fmt.Formatter(dump) {1509 pub fn fmtDebug(ty: Type) std.fmt.Formatter(dump) {
...@@ -1579,27 +1579,39 @@ pub const Type = extern union {...@@ -1579,27 +1579,39 @@ pub const Type = extern union {
15791579
1580 .@"struct" => {1580 .@"struct" => {
1581 const struct_obj = ty.castTag(.@"struct").?.data;1581 const struct_obj = ty.castTag(.@"struct").?.data;
1582 return struct_obj.owner_decl.renderFullyQualifiedName(writer);1582 return writer.print("({s} decl={d})", .{
1583 @tagName(t), struct_obj.owner_decl,
1584 });
1583 },1585 },
1584 .@"union", .union_tagged => {1586 .@"union", .union_tagged => {
1585 const union_obj = ty.cast(Payload.Union).?.data;1587 const union_obj = ty.cast(Payload.Union).?.data;
1586 return union_obj.owner_decl.renderFullyQualifiedName(writer);1588 return writer.print("({s} decl={d})", .{
1589 @tagName(t), union_obj.owner_decl,
1590 });
1587 },1591 },
1588 .enum_full, .enum_nonexhaustive => {1592 .enum_full, .enum_nonexhaustive => {
1589 const enum_full = ty.cast(Payload.EnumFull).?.data;1593 const enum_full = ty.cast(Payload.EnumFull).?.data;
1590 return enum_full.owner_decl.renderFullyQualifiedName(writer);1594 return writer.print("({s} decl={d})", .{
1595 @tagName(t), enum_full.owner_decl,
1596 });
1591 },1597 },
1592 .enum_simple => {1598 .enum_simple => {
1593 const enum_simple = ty.castTag(.enum_simple).?.data;1599 const enum_simple = ty.castTag(.enum_simple).?.data;
1594 return enum_simple.owner_decl.renderFullyQualifiedName(writer);1600 return writer.print("({s} decl={d})", .{
1601 @tagName(t), enum_simple.owner_decl,
1602 });
1595 },1603 },
1596 .enum_numbered => {1604 .enum_numbered => {
1597 const enum_numbered = ty.castTag(.enum_numbered).?.data;1605 const enum_numbered = ty.castTag(.enum_numbered).?.data;
1598 return enum_numbered.owner_decl.renderFullyQualifiedName(writer);1606 return writer.print("({s} decl={d})", .{
1607 @tagName(t), enum_numbered.owner_decl,
1608 });
1599 },1609 },
1600 .@"opaque" => {1610 .@"opaque" => {
1601 // TODO use declaration name1611 const opaque_obj = ty.castTag(.@"opaque").?.data;
1602 return writer.writeAll("opaque {}");1612 return writer.print("({s} decl={d})", .{
1613 @tagName(t), opaque_obj.owner_decl,
1614 });
1603 },1615 },
16041616
1605 .anyerror_void_error_union => return writer.writeAll("anyerror!void"),1617 .anyerror_void_error_union => return writer.writeAll("anyerror!void"),
...@@ -1845,7 +1857,9 @@ pub const Type = extern union {...@@ -1845,7 +1857,9 @@ pub const Type = extern union {
1845 },1857 },
1846 .error_set_inferred => {1858 .error_set_inferred => {
1847 const func = ty.castTag(.error_set_inferred).?.data.func;1859 const func = ty.castTag(.error_set_inferred).?.data.func;
1848 return writer.print("@typeInfo(@typeInfo(@TypeOf({s})).Fn.return_type.?).ErrorUnion.error_set", .{func.owner_decl.name});1860 return writer.print("({s} func={d})", .{
1861 @tagName(t), func.owner_decl,
1862 });
1849 },1863 },
1850 .error_set_merged => {1864 .error_set_merged => {
1851 const names = ty.castTag(.error_set_merged).?.data.keys();1865 const names = ty.castTag(.error_set_merged).?.data.keys();
...@@ -1871,15 +1885,15 @@ pub const Type = extern union {...@@ -1871,15 +1885,15 @@ pub const Type = extern union {
18711885
1872 pub const nameAllocArena = nameAlloc;1886 pub const nameAllocArena = nameAlloc;
18731887
1874 pub fn nameAlloc(ty: Type, ally: Allocator, target: Target) Allocator.Error![:0]const u8 {1888 pub fn nameAlloc(ty: Type, ally: Allocator, module: *Module) Allocator.Error![:0]const u8 {
1875 var buffer = std.ArrayList(u8).init(ally);1889 var buffer = std.ArrayList(u8).init(ally);
1876 defer buffer.deinit();1890 defer buffer.deinit();
1877 try ty.print(buffer.writer(), target);1891 try ty.print(buffer.writer(), module);
1878 return buffer.toOwnedSliceSentinel(0);1892 return buffer.toOwnedSliceSentinel(0);
1879 }1893 }
18801894
1881 /// Prints a name suitable for `@typeName`.1895 /// Prints a name suitable for `@typeName`.
1882 pub fn print(ty: Type, writer: anytype, target: Target) @TypeOf(writer).Error!void {1896 pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void {
1883 const t = ty.tag();1897 const t = ty.tag();
1884 switch (t) {1898 switch (t) {
1885 .inferred_alloc_const => unreachable,1899 .inferred_alloc_const => unreachable,
...@@ -1946,32 +1960,38 @@ pub const Type = extern union {...@@ -1946,32 +1960,38 @@ pub const Type = extern union {
19461960
1947 .empty_struct => {1961 .empty_struct => {
1948 const namespace = ty.castTag(.empty_struct).?.data;1962 const namespace = ty.castTag(.empty_struct).?.data;
1949 try namespace.renderFullyQualifiedName("", writer);1963 try namespace.renderFullyQualifiedName(mod, "", writer);
1950 },1964 },
19511965
1952 .@"struct" => {1966 .@"struct" => {
1953 const struct_obj = ty.castTag(.@"struct").?.data;1967 const struct_obj = ty.castTag(.@"struct").?.data;
1954 try struct_obj.owner_decl.renderFullyQualifiedName(writer);1968 const decl = mod.declPtr(struct_obj.owner_decl);
1969 try decl.renderFullyQualifiedName(mod, writer);
1955 },1970 },
1956 .@"union", .union_tagged => {1971 .@"union", .union_tagged => {
1957 const union_obj = ty.cast(Payload.Union).?.data;1972 const union_obj = ty.cast(Payload.Union).?.data;
1958 try union_obj.owner_decl.renderFullyQualifiedName(writer);1973 const decl = mod.declPtr(union_obj.owner_decl);
1974 try decl.renderFullyQualifiedName(mod, writer);
1959 },1975 },
1960 .enum_full, .enum_nonexhaustive => {1976 .enum_full, .enum_nonexhaustive => {
1961 const enum_full = ty.cast(Payload.EnumFull).?.data;1977 const enum_full = ty.cast(Payload.EnumFull).?.data;
1962 try enum_full.owner_decl.renderFullyQualifiedName(writer);1978 const decl = mod.declPtr(enum_full.owner_decl);
1979 try decl.renderFullyQualifiedName(mod, writer);
1963 },1980 },
1964 .enum_simple => {1981 .enum_simple => {
1965 const enum_simple = ty.castTag(.enum_simple).?.data;1982 const enum_simple = ty.castTag(.enum_simple).?.data;
1966 try enum_simple.owner_decl.renderFullyQualifiedName(writer);1983 const decl = mod.declPtr(enum_simple.owner_decl);
1984 try decl.renderFullyQualifiedName(mod, writer);
1967 },1985 },
1968 .enum_numbered => {1986 .enum_numbered => {
1969 const enum_numbered = ty.castTag(.enum_numbered).?.data;1987 const enum_numbered = ty.castTag(.enum_numbered).?.data;
1970 try enum_numbered.owner_decl.renderFullyQualifiedName(writer);1988 const decl = mod.declPtr(enum_numbered.owner_decl);
1989 try decl.renderFullyQualifiedName(mod, writer);
1971 },1990 },
1972 .@"opaque" => {1991 .@"opaque" => {
1973 const opaque_obj = ty.cast(Payload.Opaque).?.data;1992 const opaque_obj = ty.cast(Payload.Opaque).?.data;
1974 try opaque_obj.owner_decl.renderFullyQualifiedName(writer);1993 const decl = mod.declPtr(opaque_obj.owner_decl);
1994 try decl.renderFullyQualifiedName(mod, writer);
1975 },1995 },
19761996
1977 .anyerror_void_error_union => try writer.writeAll("anyerror!void"),1997 .anyerror_void_error_union => try writer.writeAll("anyerror!void"),
...@@ -1990,7 +2010,8 @@ pub const Type = extern union {...@@ -1990,7 +2010,8 @@ pub const Type = extern union {
1990 const func = ty.castTag(.error_set_inferred).?.data.func;2010 const func = ty.castTag(.error_set_inferred).?.data.func;
19912011
1992 try writer.writeAll("@typeInfo(@typeInfo(@TypeOf(");2012 try writer.writeAll("@typeInfo(@typeInfo(@TypeOf(");
1993 try func.owner_decl.renderFullyQualifiedName(writer);2013 const owner_decl = mod.declPtr(func.owner_decl);
2014 try owner_decl.renderFullyQualifiedName(mod, writer);
1994 try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set");2015 try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set");
1995 },2016 },
19962017
...@@ -1999,7 +2020,7 @@ pub const Type = extern union {...@@ -1999,7 +2020,7 @@ pub const Type = extern union {
1999 try writer.writeAll("fn(");2020 try writer.writeAll("fn(");
2000 for (fn_info.param_types) |param_ty, i| {2021 for (fn_info.param_types) |param_ty, i| {
2001 if (i != 0) try writer.writeAll(", ");2022 if (i != 0) try writer.writeAll(", ");
2002 try print(param_ty, writer, target);2023 try print(param_ty, writer, mod);
2003 }2024 }
2004 if (fn_info.is_var_args) {2025 if (fn_info.is_var_args) {
2005 if (fn_info.param_types.len != 0) {2026 if (fn_info.param_types.len != 0) {
...@@ -2016,14 +2037,14 @@ pub const Type = extern union {...@@ -2016,14 +2037,14 @@ pub const Type = extern union {
2016 if (fn_info.alignment != 0) {2037 if (fn_info.alignment != 0) {
2017 try writer.print("align({d}) ", .{fn_info.alignment});2038 try writer.print("align({d}) ", .{fn_info.alignment});
2018 }2039 }
2019 try print(fn_info.return_type, writer, target);2040 try print(fn_info.return_type, writer, mod);
2020 },2041 },
20212042
2022 .error_union => {2043 .error_union => {
2023 const error_union = ty.castTag(.error_union).?.data;2044 const error_union = ty.castTag(.error_union).?.data;
2024 try print(error_union.error_set, writer, target);2045 try print(error_union.error_set, writer, mod);
2025 try writer.writeAll("!");2046 try writer.writeAll("!");
2026 try print(error_union.payload, writer, target);2047 try print(error_union.payload, writer, mod);
2027 },2048 },
20282049
2029 .array_u8 => {2050 .array_u8 => {
...@@ -2037,21 +2058,21 @@ pub const Type = extern union {...@@ -2037,21 +2058,21 @@ pub const Type = extern union {
2037 .vector => {2058 .vector => {
2038 const payload = ty.castTag(.vector).?.data;2059 const payload = ty.castTag(.vector).?.data;
2039 try writer.print("@Vector({d}, ", .{payload.len});2060 try writer.print("@Vector({d}, ", .{payload.len});
2040 try print(payload.elem_type, writer, target);2061 try print(payload.elem_type, writer, mod);
2041 try writer.writeAll(")");2062 try writer.writeAll(")");
2042 },2063 },
2043 .array => {2064 .array => {
2044 const payload = ty.castTag(.array).?.data;2065 const payload = ty.castTag(.array).?.data;
2045 try writer.print("[{d}]", .{payload.len});2066 try writer.print("[{d}]", .{payload.len});
2046 try print(payload.elem_type, writer, target);2067 try print(payload.elem_type, writer, mod);
2047 },2068 },
2048 .array_sentinel => {2069 .array_sentinel => {
2049 const payload = ty.castTag(.array_sentinel).?.data;2070 const payload = ty.castTag(.array_sentinel).?.data;
2050 try writer.print("[{d}:{}]", .{2071 try writer.print("[{d}:{}]", .{
2051 payload.len,2072 payload.len,
2052 payload.sentinel.fmtValue(payload.elem_type, target),2073 payload.sentinel.fmtValue(payload.elem_type, mod),
2053 });2074 });
2054 try print(payload.elem_type, writer, target);2075 try print(payload.elem_type, writer, mod);
2055 },2076 },
2056 .tuple => {2077 .tuple => {
2057 const tuple = ty.castTag(.tuple).?.data;2078 const tuple = ty.castTag(.tuple).?.data;
...@@ -2063,9 +2084,9 @@ pub const Type = extern union {...@@ -2063,9 +2084,9 @@ pub const Type = extern union {
2063 if (val.tag() != .unreachable_value) {2084 if (val.tag() != .unreachable_value) {
2064 try writer.writeAll("comptime ");2085 try writer.writeAll("comptime ");
2065 }2086 }
2066 try print(field_ty, writer, target);2087 try print(field_ty, writer, mod);
2067 if (val.tag() != .unreachable_value) {2088 if (val.tag() != .unreachable_value) {
2068 try writer.print(" = {}", .{val.fmtValue(field_ty, target)});2089 try writer.print(" = {}", .{val.fmtValue(field_ty, mod)});
2069 }2090 }
2070 }2091 }
2071 try writer.writeAll("}");2092 try writer.writeAll("}");
...@@ -2083,10 +2104,10 @@ pub const Type = extern union {...@@ -2083,10 +2104,10 @@ pub const Type = extern union {
2083 try writer.writeAll(anon_struct.names[i]);2104 try writer.writeAll(anon_struct.names[i]);
2084 try writer.writeAll(": ");2105 try writer.writeAll(": ");
20852106
2086 try print(field_ty, writer, target);2107 try print(field_ty, writer, mod);
20872108
2088 if (val.tag() != .unreachable_value) {2109 if (val.tag() != .unreachable_value) {
2089 try writer.print(" = {}", .{val.fmtValue(field_ty, target)});2110 try writer.print(" = {}", .{val.fmtValue(field_ty, mod)});
2090 }2111 }
2091 }2112 }
2092 try writer.writeAll("}");2113 try writer.writeAll("}");
...@@ -2106,8 +2127,8 @@ pub const Type = extern union {...@@ -2106,8 +2127,8 @@ pub const Type = extern union {
21062127
2107 if (info.sentinel) |s| switch (info.size) {2128 if (info.sentinel) |s| switch (info.size) {
2108 .One, .C => unreachable,2129 .One, .C => unreachable,
2109 .Many => try writer.print("[*:{}]", .{s.fmtValue(info.pointee_type, target)}),2130 .Many => try writer.print("[*:{}]", .{s.fmtValue(info.pointee_type, mod)}),
2110 .Slice => try writer.print("[:{}]", .{s.fmtValue(info.pointee_type, target)}),2131 .Slice => try writer.print("[:{}]", .{s.fmtValue(info.pointee_type, mod)}),
2111 } else switch (info.size) {2132 } else switch (info.size) {
2112 .One => try writer.writeAll("*"),2133 .One => try writer.writeAll("*"),
2113 .Many => try writer.writeAll("[*]"),2134 .Many => try writer.writeAll("[*]"),
...@@ -2129,7 +2150,7 @@ pub const Type = extern union {...@@ -2129,7 +2150,7 @@ pub const Type = extern union {
2129 if (info.@"volatile") try writer.writeAll("volatile ");2150 if (info.@"volatile") try writer.writeAll("volatile ");
2130 if (info.@"allowzero" and info.size != .C) try writer.writeAll("allowzero ");2151 if (info.@"allowzero" and info.size != .C) try writer.writeAll("allowzero ");
21312152
2132 try print(info.pointee_type, writer, target);2153 try print(info.pointee_type, writer, mod);
2133 },2154 },
21342155
2135 .int_signed => {2156 .int_signed => {
...@@ -2143,22 +2164,22 @@ pub const Type = extern union {...@@ -2143,22 +2164,22 @@ pub const Type = extern union {
2143 .optional => {2164 .optional => {
2144 const child_type = ty.castTag(.optional).?.data;2165 const child_type = ty.castTag(.optional).?.data;
2145 try writer.writeByte('?');2166 try writer.writeByte('?');
2146 try print(child_type, writer, target);2167 try print(child_type, writer, mod);
2147 },2168 },
2148 .optional_single_mut_pointer => {2169 .optional_single_mut_pointer => {
2149 const pointee_type = ty.castTag(.optional_single_mut_pointer).?.data;2170 const pointee_type = ty.castTag(.optional_single_mut_pointer).?.data;
2150 try writer.writeAll("?*");2171 try writer.writeAll("?*");
2151 try print(pointee_type, writer, target);2172 try print(pointee_type, writer, mod);
2152 },2173 },
2153 .optional_single_const_pointer => {2174 .optional_single_const_pointer => {
2154 const pointee_type = ty.castTag(.optional_single_const_pointer).?.data;2175 const pointee_type = ty.castTag(.optional_single_const_pointer).?.data;
2155 try writer.writeAll("?*const ");2176 try writer.writeAll("?*const ");
2156 try print(pointee_type, writer, target);2177 try print(pointee_type, writer, mod);
2157 },2178 },
2158 .anyframe_T => {2179 .anyframe_T => {
2159 const return_type = ty.castTag(.anyframe_T).?.data;2180 const return_type = ty.castTag(.anyframe_T).?.data;
2160 try writer.print("anyframe->", .{});2181 try writer.print("anyframe->", .{});
2161 try print(return_type, writer, target);2182 try print(return_type, writer, mod);
2162 },2183 },
2163 .error_set => {2184 .error_set => {
2164 const names = ty.castTag(.error_set).?.data.names.keys();2185 const names = ty.castTag(.error_set).?.data.names.keys();
...@@ -3834,8 +3855,8 @@ pub const Type = extern union {...@@ -3834,8 +3855,8 @@ pub const Type = extern union {
3834 /// For [*]T, returns *T3855 /// For [*]T, returns *T
3835 /// For []T, returns *T3856 /// For []T, returns *T
3836 /// Handles const-ness and address spaces in particular.3857 /// Handles const-ness and address spaces in particular.
3837 pub fn elemPtrType(ptr_ty: Type, arena: Allocator, target: Target) !Type {3858 pub fn elemPtrType(ptr_ty: Type, arena: Allocator, mod: *Module) !Type {
3838 return try Type.ptr(arena, target, .{3859 return try Type.ptr(arena, mod, .{
3839 .pointee_type = ptr_ty.elemType2(),3860 .pointee_type = ptr_ty.elemType2(),
3840 .mutable = ptr_ty.ptrIsMutable(),3861 .mutable = ptr_ty.ptrIsMutable(),
3841 .@"addrspace" = ptr_ty.ptrAddressSpace(),3862 .@"addrspace" = ptr_ty.ptrAddressSpace(),
...@@ -3948,9 +3969,9 @@ pub const Type = extern union {...@@ -3948,9 +3969,9 @@ pub const Type = extern union {
3948 return union_obj.fields;3969 return union_obj.fields;
3949 }3970 }
39503971
3951 pub fn unionFieldType(ty: Type, enum_tag: Value, target: Target) Type {3972 pub fn unionFieldType(ty: Type, enum_tag: Value, mod: *Module) Type {
3952 const union_obj = ty.cast(Payload.Union).?.data;3973 const union_obj = ty.cast(Payload.Union).?.data;
3953 const index = union_obj.tag_ty.enumTagFieldIndex(enum_tag, target).?;3974 const index = union_obj.tag_ty.enumTagFieldIndex(enum_tag, mod).?;
3954 assert(union_obj.haveFieldTypes());3975 assert(union_obj.haveFieldTypes());
3955 return union_obj.fields.values()[index].ty;3976 return union_obj.fields.values()[index].ty;
3956 }3977 }
...@@ -4970,20 +4991,20 @@ pub const Type = extern union {...@@ -4970,20 +4991,20 @@ pub const Type = extern union {
4970 /// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or4991 /// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or
4971 /// an integer which represents the enum value. Returns the field index in4992 /// an integer which represents the enum value. Returns the field index in
4972 /// declaration order, or `null` if `enum_tag` does not match any field.4993 /// declaration order, or `null` if `enum_tag` does not match any field.
4973 pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, target: Target) ?usize {4994 pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, mod: *Module) ?usize {
4974 if (enum_tag.castTag(.enum_field_index)) |payload| {4995 if (enum_tag.castTag(.enum_field_index)) |payload| {
4975 return @as(usize, payload.data);4996 return @as(usize, payload.data);
4976 }4997 }
4977 const S = struct {4998 const S = struct {
4978 fn fieldWithRange(int_ty: Type, int_val: Value, end: usize, tg: Target) ?usize {4999 fn fieldWithRange(int_ty: Type, int_val: Value, end: usize, m: *Module) ?usize {
4979 if (int_val.compareWithZero(.lt)) return null;5000 if (int_val.compareWithZero(.lt)) return null;
4980 var end_payload: Value.Payload.U64 = .{5001 var end_payload: Value.Payload.U64 = .{
4981 .base = .{ .tag = .int_u64 },5002 .base = .{ .tag = .int_u64 },
4982 .data = end,5003 .data = end,
4983 };5004 };
4984 const end_val = Value.initPayload(&end_payload.base);5005 const end_val = Value.initPayload(&end_payload.base);
4985 if (int_val.compare(.gte, end_val, int_ty, tg)) return null;5006 if (int_val.compare(.gte, end_val, int_ty, m)) return null;
4986 return @intCast(usize, int_val.toUnsignedInt(tg));5007 return @intCast(usize, int_val.toUnsignedInt(m.getTarget()));
4987 }5008 }
4988 };5009 };
4989 switch (ty.tag()) {5010 switch (ty.tag()) {
...@@ -4991,11 +5012,11 @@ pub const Type = extern union {...@@ -4991,11 +5012,11 @@ pub const Type = extern union {
4991 const enum_full = ty.cast(Payload.EnumFull).?.data;5012 const enum_full = ty.cast(Payload.EnumFull).?.data;
4992 const tag_ty = enum_full.tag_ty;5013 const tag_ty = enum_full.tag_ty;
4993 if (enum_full.values.count() == 0) {5014 if (enum_full.values.count() == 0) {
4994 return S.fieldWithRange(tag_ty, enum_tag, enum_full.fields.count(), target);5015 return S.fieldWithRange(tag_ty, enum_tag, enum_full.fields.count(), mod);
4995 } else {5016 } else {
4996 return enum_full.values.getIndexContext(enum_tag, .{5017 return enum_full.values.getIndexContext(enum_tag, .{
4997 .ty = tag_ty,5018 .ty = tag_ty,
4998 .target = target,5019 .mod = mod,
4999 });5020 });
5000 }5021 }
5001 },5022 },
...@@ -5003,11 +5024,11 @@ pub const Type = extern union {...@@ -5003,11 +5024,11 @@ pub const Type = extern union {
5003 const enum_obj = ty.castTag(.enum_numbered).?.data;5024 const enum_obj = ty.castTag(.enum_numbered).?.data;
5004 const tag_ty = enum_obj.tag_ty;5025 const tag_ty = enum_obj.tag_ty;
5005 if (enum_obj.values.count() == 0) {5026 if (enum_obj.values.count() == 0) {
5006 return S.fieldWithRange(tag_ty, enum_tag, enum_obj.fields.count(), target);5027 return S.fieldWithRange(tag_ty, enum_tag, enum_obj.fields.count(), mod);
5007 } else {5028 } else {
5008 return enum_obj.values.getIndexContext(enum_tag, .{5029 return enum_obj.values.getIndexContext(enum_tag, .{
5009 .ty = tag_ty,5030 .ty = tag_ty,
5010 .target = target,5031 .mod = mod,
5011 });5032 });
5012 }5033 }
5013 },5034 },
...@@ -5020,7 +5041,7 @@ pub const Type = extern union {...@@ -5020,7 +5041,7 @@ pub const Type = extern union {
5020 .data = bits,5041 .data = bits,
5021 };5042 };
5022 const tag_ty = Type.initPayload(&buffer.base);5043 const tag_ty = Type.initPayload(&buffer.base);
5023 return S.fieldWithRange(tag_ty, enum_tag, fields_len, target);5044 return S.fieldWithRange(tag_ty, enum_tag, fields_len, mod);
5024 },5045 },
5025 .atomic_order,5046 .atomic_order,
5026 .atomic_rmw_op,5047 .atomic_rmw_op,
...@@ -5224,32 +5245,35 @@ pub const Type = extern union {...@@ -5224,32 +5245,35 @@ pub const Type = extern union {
5224 }5245 }
5225 }5246 }
52265247
5227 pub fn declSrcLoc(ty: Type) Module.SrcLoc {5248 pub fn declSrcLoc(ty: Type, mod: *Module) Module.SrcLoc {
5228 return declSrcLocOrNull(ty).?;5249 return declSrcLocOrNull(ty, mod).?;
5229 }5250 }
52305251
5231 pub fn declSrcLocOrNull(ty: Type) ?Module.SrcLoc {5252 pub fn declSrcLocOrNull(ty: Type, mod: *Module) ?Module.SrcLoc {
5232 switch (ty.tag()) {5253 switch (ty.tag()) {
5233 .enum_full, .enum_nonexhaustive => {5254 .enum_full, .enum_nonexhaustive => {
5234 const enum_full = ty.cast(Payload.EnumFull).?.data;5255 const enum_full = ty.cast(Payload.EnumFull).?.data;
5235 return enum_full.srcLoc();5256 return enum_full.srcLoc(mod);
5257 },
5258 .enum_numbered => {
5259 const enum_numbered = ty.castTag(.enum_numbered).?.data;
5260 return enum_numbered.srcLoc(mod);
5236 },5261 },
5237 .enum_numbered => return ty.castTag(.enum_numbered).?.data.srcLoc(),
5238 .enum_simple => {5262 .enum_simple => {
5239 const enum_simple = ty.castTag(.enum_simple).?.data;5263 const enum_simple = ty.castTag(.enum_simple).?.data;
5240 return enum_simple.srcLoc();5264 return enum_simple.srcLoc(mod);
5241 },5265 },
5242 .@"struct" => {5266 .@"struct" => {
5243 const struct_obj = ty.castTag(.@"struct").?.data;5267 const struct_obj = ty.castTag(.@"struct").?.data;
5244 return struct_obj.srcLoc();5268 return struct_obj.srcLoc(mod);
5245 },5269 },
5246 .error_set => {5270 .error_set => {
5247 const error_set = ty.castTag(.error_set).?.data;5271 const error_set = ty.castTag(.error_set).?.data;
5248 return error_set.srcLoc();5272 return error_set.srcLoc(mod);
5249 },5273 },
5250 .@"union", .union_tagged => {5274 .@"union", .union_tagged => {
5251 const union_obj = ty.cast(Payload.Union).?.data;5275 const union_obj = ty.cast(Payload.Union).?.data;
5252 return union_obj.srcLoc();5276 return union_obj.srcLoc(mod);
5253 },5277 },
5254 .atomic_order,5278 .atomic_order,
5255 .atomic_rmw_op,5279 .atomic_rmw_op,
...@@ -5268,7 +5292,7 @@ pub const Type = extern union {...@@ -5268,7 +5292,7 @@ pub const Type = extern union {
5268 }5292 }
5269 }5293 }
52705294
5271 pub fn getOwnerDecl(ty: Type) *Module.Decl {5295 pub fn getOwnerDecl(ty: Type) Module.Decl.Index {
5272 switch (ty.tag()) {5296 switch (ty.tag()) {
5273 .enum_full, .enum_nonexhaustive => {5297 .enum_full, .enum_nonexhaustive => {
5274 const enum_full = ty.cast(Payload.EnumFull).?.data;5298 const enum_full = ty.cast(Payload.EnumFull).?.data;
...@@ -5357,30 +5381,30 @@ pub const Type = extern union {...@@ -5357,30 +5381,30 @@ pub const Type = extern union {
5357 }5381 }
53585382
5359 /// Asserts the type is an enum.5383 /// Asserts the type is an enum.
5360 pub fn enumHasInt(ty: Type, int: Value, target: Target) bool {5384 pub fn enumHasInt(ty: Type, int: Value, mod: *Module) bool {
5361 const S = struct {5385 const S = struct {
5362 fn intInRange(tag_ty: Type, int_val: Value, end: usize, tg: Target) bool {5386 fn intInRange(tag_ty: Type, int_val: Value, end: usize, m: *Module) bool {
5363 if (int_val.compareWithZero(.lt)) return false;5387 if (int_val.compareWithZero(.lt)) return false;
5364 var end_payload: Value.Payload.U64 = .{5388 var end_payload: Value.Payload.U64 = .{
5365 .base = .{ .tag = .int_u64 },5389 .base = .{ .tag = .int_u64 },
5366 .data = end,5390 .data = end,
5367 };5391 };
5368 const end_val = Value.initPayload(&end_payload.base);5392 const end_val = Value.initPayload(&end_payload.base);
5369 if (int_val.compare(.gte, end_val, tag_ty, tg)) return false;5393 if (int_val.compare(.gte, end_val, tag_ty, m)) return false;
5370 return true;5394 return true;
5371 }5395 }
5372 };5396 };
5373 switch (ty.tag()) {5397 switch (ty.tag()) {
5374 .enum_nonexhaustive => return int.intFitsInType(ty, target),5398 .enum_nonexhaustive => return int.intFitsInType(ty, mod.getTarget()),
5375 .enum_full => {5399 .enum_full => {
5376 const enum_full = ty.castTag(.enum_full).?.data;5400 const enum_full = ty.castTag(.enum_full).?.data;
5377 const tag_ty = enum_full.tag_ty;5401 const tag_ty = enum_full.tag_ty;
5378 if (enum_full.values.count() == 0) {5402 if (enum_full.values.count() == 0) {
5379 return S.intInRange(tag_ty, int, enum_full.fields.count(), target);5403 return S.intInRange(tag_ty, int, enum_full.fields.count(), mod);
5380 } else {5404 } else {
5381 return enum_full.values.containsContext(int, .{5405 return enum_full.values.containsContext(int, .{
5382 .ty = tag_ty,5406 .ty = tag_ty,
5383 .target = target,5407 .mod = mod,
5384 });5408 });
5385 }5409 }
5386 },5410 },
...@@ -5388,11 +5412,11 @@ pub const Type = extern union {...@@ -5388,11 +5412,11 @@ pub const Type = extern union {
5388 const enum_obj = ty.castTag(.enum_numbered).?.data;5412 const enum_obj = ty.castTag(.enum_numbered).?.data;
5389 const tag_ty = enum_obj.tag_ty;5413 const tag_ty = enum_obj.tag_ty;
5390 if (enum_obj.values.count() == 0) {5414 if (enum_obj.values.count() == 0) {
5391 return S.intInRange(tag_ty, int, enum_obj.fields.count(), target);5415 return S.intInRange(tag_ty, int, enum_obj.fields.count(), mod);
5392 } else {5416 } else {
5393 return enum_obj.values.containsContext(int, .{5417 return enum_obj.values.containsContext(int, .{
5394 .ty = tag_ty,5418 .ty = tag_ty,
5395 .target = target,5419 .mod = mod,
5396 });5420 });
5397 }5421 }
5398 },5422 },
...@@ -5405,7 +5429,7 @@ pub const Type = extern union {...@@ -5405,7 +5429,7 @@ pub const Type = extern union {
5405 .data = bits,5429 .data = bits,
5406 };5430 };
5407 const tag_ty = Type.initPayload(&buffer.base);5431 const tag_ty = Type.initPayload(&buffer.base);
5408 return S.intInRange(tag_ty, int, fields_len, target);5432 return S.intInRange(tag_ty, int, fields_len, mod);
5409 },5433 },
5410 .atomic_order,5434 .atomic_order,
5411 .atomic_rmw_op,5435 .atomic_rmw_op,
...@@ -5937,7 +5961,9 @@ pub const Type = extern union {...@@ -5937,7 +5961,9 @@ pub const Type = extern union {
5937 pub const @"anyopaque" = initTag(.anyopaque);5961 pub const @"anyopaque" = initTag(.anyopaque);
5938 pub const @"null" = initTag(.@"null");5962 pub const @"null" = initTag(.@"null");
59395963
5940 pub fn ptr(arena: Allocator, target: Target, data: Payload.Pointer.Data) !Type {5964 pub fn ptr(arena: Allocator, mod: *Module, data: Payload.Pointer.Data) !Type {
5965 const target = mod.getTarget();
5966
5941 var d = data;5967 var d = data;
59425968
5943 if (d.size == .C) {5969 if (d.size == .C) {
...@@ -5967,7 +5993,7 @@ pub const Type = extern union {...@@ -5967,7 +5993,7 @@ pub const Type = extern union {
5967 d.bit_offset == 0 and d.host_size == 0 and !d.@"allowzero" and !d.@"volatile")5993 d.bit_offset == 0 and d.host_size == 0 and !d.@"allowzero" and !d.@"volatile")
5968 {5994 {
5969 if (d.sentinel) |sent| {5995 if (d.sentinel) |sent| {
5970 if (!d.mutable and d.pointee_type.eql(Type.u8, target)) {5996 if (!d.mutable and d.pointee_type.eql(Type.u8, mod)) {
5971 switch (d.size) {5997 switch (d.size) {
5972 .Slice => {5998 .Slice => {
5973 if (sent.compareWithZero(.eq)) {5999 if (sent.compareWithZero(.eq)) {
...@@ -5982,7 +6008,7 @@ pub const Type = extern union {...@@ -5982,7 +6008,7 @@ pub const Type = extern union {
5982 else => {},6008 else => {},
5983 }6009 }
5984 }6010 }
5985 } else if (!d.mutable and d.pointee_type.eql(Type.u8, target)) {6011 } else if (!d.mutable and d.pointee_type.eql(Type.u8, mod)) {
5986 switch (d.size) {6012 switch (d.size) {
5987 .Slice => return Type.initTag(.const_slice_u8),6013 .Slice => return Type.initTag(.const_slice_u8),
5988 .Many => return Type.initTag(.manyptr_const_u8),6014 .Many => return Type.initTag(.manyptr_const_u8),
...@@ -6016,11 +6042,11 @@ pub const Type = extern union {...@@ -6016,11 +6042,11 @@ pub const Type = extern union {
6016 len: u64,6042 len: u64,
6017 sent: ?Value,6043 sent: ?Value,
6018 elem_type: Type,6044 elem_type: Type,
6019 target: Target,6045 mod: *Module,
6020 ) Allocator.Error!Type {6046 ) Allocator.Error!Type {
6021 if (elem_type.eql(Type.u8, target)) {6047 if (elem_type.eql(Type.u8, mod)) {
6022 if (sent) |some| {6048 if (sent) |some| {
6023 if (some.eql(Value.zero, elem_type, target)) {6049 if (some.eql(Value.zero, elem_type, mod)) {
6024 return Tag.array_u8_sentinel_0.create(arena, len);6050 return Tag.array_u8_sentinel_0.create(arena, len);
6025 }6051 }
6026 } else {6052 } else {
...@@ -6067,11 +6093,11 @@ pub const Type = extern union {...@@ -6067,11 +6093,11 @@ pub const Type = extern union {
6067 arena: Allocator,6093 arena: Allocator,
6068 error_set: Type,6094 error_set: Type,
6069 payload: Type,6095 payload: Type,
6070 target: Target,6096 mod: *Module,
6071 ) Allocator.Error!Type {6097 ) Allocator.Error!Type {
6072 assert(error_set.zigTypeTag() == .ErrorSet);6098 assert(error_set.zigTypeTag() == .ErrorSet);
6073 if (error_set.eql(Type.@"anyerror", target) and6099 if (error_set.eql(Type.@"anyerror", mod) and
6074 payload.eql(Type.void, target))6100 payload.eql(Type.void, mod))
6075 {6101 {
6076 return Type.initTag(.anyerror_void_error_union);6102 return Type.initTag(.anyerror_void_error_union);
6077 }6103 }
src/value.zig+122-139
...@@ -731,16 +731,16 @@ pub const Value = extern union {...@@ -731,16 +731,16 @@ pub const Value = extern union {
731 .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", options, out_stream),731 .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", options, out_stream),
732 .int_big_positive => return out_stream.print("{}", .{val.castTag(.int_big_positive).?.asBigInt()}),732 .int_big_positive => return out_stream.print("{}", .{val.castTag(.int_big_positive).?.asBigInt()}),
733 .int_big_negative => return out_stream.print("{}", .{val.castTag(.int_big_negative).?.asBigInt()}),733 .int_big_negative => return out_stream.print("{}", .{val.castTag(.int_big_negative).?.asBigInt()}),
734 .function => return out_stream.print("(function '{s}')", .{val.castTag(.function).?.data.owner_decl.name}),734 .function => return out_stream.print("(function decl={d})", .{val.castTag(.function).?.data.owner_decl}),
735 .extern_fn => return out_stream.writeAll("(extern function)"),735 .extern_fn => return out_stream.writeAll("(extern function)"),
736 .variable => return out_stream.writeAll("(variable)"),736 .variable => return out_stream.writeAll("(variable)"),
737 .decl_ref_mut => {737 .decl_ref_mut => {
738 const decl = val.castTag(.decl_ref_mut).?.data.decl;738 const decl_index = val.castTag(.decl_ref_mut).?.data.decl_index;
739 return out_stream.print("(decl_ref_mut '{s}')", .{decl.name});739 return out_stream.print("(decl_ref_mut {d})", .{decl_index});
740 },740 },
741 .decl_ref => {741 .decl_ref => {
742 const decl = val.castTag(.decl_ref).?.data;742 const decl_index = val.castTag(.decl_ref).?.data;
743 return out_stream.print("(decl ref '{s}')", .{decl.name});743 return out_stream.print("(decl_ref {d})", .{decl_index});
744 },744 },
745 .elem_ptr => {745 .elem_ptr => {
746 const elem_ptr = val.castTag(.elem_ptr).?.data;746 const elem_ptr = val.castTag(.elem_ptr).?.data;
...@@ -798,16 +798,17 @@ pub const Value = extern union {...@@ -798,16 +798,17 @@ pub const Value = extern union {
798 return .{ .data = val };798 return .{ .data = val };
799 }799 }
800800
801 pub fn fmtValue(val: Value, ty: Type, target: Target) std.fmt.Formatter(TypedValue.format) {801 pub fn fmtValue(val: Value, ty: Type, mod: *Module) std.fmt.Formatter(TypedValue.format) {
802 return .{ .data = .{802 return .{ .data = .{
803 .tv = .{ .ty = ty, .val = val },803 .tv = .{ .ty = ty, .val = val },
804 .target = target,804 .mod = mod,
805 } };805 } };
806 }806 }
807807
808 /// Asserts that the value is representable as an array of bytes.808 /// Asserts that the value is representable as an array of bytes.
809 /// Copies the value into a freshly allocated slice of memory, which is owned by the caller.809 /// Copies the value into a freshly allocated slice of memory, which is owned by the caller.
810 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, target: Target) ![]u8 {810 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module) ![]u8 {
811 const target = mod.getTarget();
811 switch (val.tag()) {812 switch (val.tag()) {
812 .bytes => {813 .bytes => {
813 const bytes = val.castTag(.bytes).?.data;814 const bytes = val.castTag(.bytes).?.data;
...@@ -823,25 +824,26 @@ pub const Value = extern union {...@@ -823,25 +824,26 @@ pub const Value = extern union {
823 return result;824 return result;
824 },825 },
825 .decl_ref => {826 .decl_ref => {
826 const decl = val.castTag(.decl_ref).?.data;827 const decl_index = val.castTag(.decl_ref).?.data;
828 const decl = mod.declPtr(decl_index);
827 const decl_val = try decl.value();829 const decl_val = try decl.value();
828 return decl_val.toAllocatedBytes(decl.ty, allocator, target);830 return decl_val.toAllocatedBytes(decl.ty, allocator, mod);
829 },831 },
830 .the_only_possible_value => return &[_]u8{},832 .the_only_possible_value => return &[_]u8{},
831 .slice => {833 .slice => {
832 const slice = val.castTag(.slice).?.data;834 const slice = val.castTag(.slice).?.data;
833 return arrayToAllocatedBytes(slice.ptr, slice.len.toUnsignedInt(target), allocator, target);835 return arrayToAllocatedBytes(slice.ptr, slice.len.toUnsignedInt(target), allocator, mod);
834 },836 },
835 else => return arrayToAllocatedBytes(val, ty.arrayLen(), allocator, target),837 else => return arrayToAllocatedBytes(val, ty.arrayLen(), allocator, mod),
836 }838 }
837 }839 }
838840
839 fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator, target: Target) ![]u8 {841 fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator, mod: *Module) ![]u8 {
840 const result = try allocator.alloc(u8, @intCast(usize, len));842 const result = try allocator.alloc(u8, @intCast(usize, len));
841 var elem_value_buf: ElemValueBuffer = undefined;843 var elem_value_buf: ElemValueBuffer = undefined;
842 for (result) |*elem, i| {844 for (result) |*elem, i| {
843 const elem_val = val.elemValueBuffer(i, &elem_value_buf);845 const elem_val = val.elemValueBuffer(mod, i, &elem_value_buf);
844 elem.* = @intCast(u8, elem_val.toUnsignedInt(target));846 elem.* = @intCast(u8, elem_val.toUnsignedInt(mod.getTarget()));
845 }847 }
846 return result;848 return result;
847 }849 }
...@@ -1164,7 +1166,7 @@ pub const Value = extern union {...@@ -1164,7 +1166,7 @@ pub const Value = extern union {
1164 var elem_value_buf: ElemValueBuffer = undefined;1166 var elem_value_buf: ElemValueBuffer = undefined;
1165 var buf_off: usize = 0;1167 var buf_off: usize = 0;
1166 while (elem_i < len) : (elem_i += 1) {1168 while (elem_i < len) : (elem_i += 1) {
1167 const elem_val = val.elemValueBuffer(elem_i, &elem_value_buf);1169 const elem_val = val.elemValueBuffer(mod, elem_i, &elem_value_buf);
1168 writeToMemory(elem_val, elem_ty, mod, buffer[buf_off..]);1170 writeToMemory(elem_val, elem_ty, mod, buffer[buf_off..]);
1169 buf_off += elem_size;1171 buf_off += elem_size;
1170 }1172 }
...@@ -1975,34 +1977,47 @@ pub const Value = extern union {...@@ -1975,34 +1977,47 @@ pub const Value = extern union {
19751977
1976 /// Asserts the values are comparable. Both operands have type `ty`.1978 /// Asserts the values are comparable. Both operands have type `ty`.
1977 /// Vector results will be reduced with AND.1979 /// Vector results will be reduced with AND.
1978 pub fn compare(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, target: Target) bool {1980 pub fn compare(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, mod: *Module) bool {
1979 if (ty.zigTypeTag() == .Vector) {1981 if (ty.zigTypeTag() == .Vector) {
1980 var i: usize = 0;1982 var i: usize = 0;
1981 while (i < ty.vectorLen()) : (i += 1) {1983 while (i < ty.vectorLen()) : (i += 1) {
1982 if (!compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType(), target)) {1984 if (!compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType(), mod)) {
1983 return false;1985 return false;
1984 }1986 }
1985 }1987 }
1986 return true;1988 return true;
1987 }1989 }
1988 return compareScalar(lhs, op, rhs, ty, target);1990 return compareScalar(lhs, op, rhs, ty, mod);
1989 }1991 }
19901992
1991 /// Asserts the values are comparable. Both operands have type `ty`.1993 /// Asserts the values are comparable. Both operands have type `ty`.
1992 pub fn compareScalar(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, target: Target) bool {1994 pub fn compareScalar(
1995 lhs: Value,
1996 op: std.math.CompareOperator,
1997 rhs: Value,
1998 ty: Type,
1999 mod: *Module,
2000 ) bool {
1993 return switch (op) {2001 return switch (op) {
1994 .eq => lhs.eql(rhs, ty, target),2002 .eq => lhs.eql(rhs, ty, mod),
1995 .neq => !lhs.eql(rhs, ty, target),2003 .neq => !lhs.eql(rhs, ty, mod),
1996 else => compareHetero(lhs, op, rhs, target),2004 else => compareHetero(lhs, op, rhs, mod.getTarget()),
1997 };2005 };
1998 }2006 }
19992007
2000 /// Asserts the values are comparable vectors of type `ty`.2008 /// Asserts the values are comparable vectors of type `ty`.
2001 pub fn compareVector(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {2009 pub fn compareVector(
2010 lhs: Value,
2011 op: std.math.CompareOperator,
2012 rhs: Value,
2013 ty: Type,
2014 allocator: Allocator,
2015 mod: *Module,
2016 ) !Value {
2002 assert(ty.zigTypeTag() == .Vector);2017 assert(ty.zigTypeTag() == .Vector);
2003 const result_data = try allocator.alloc(Value, ty.vectorLen());2018 const result_data = try allocator.alloc(Value, ty.vectorLen());
2004 for (result_data) |*scalar, i| {2019 for (result_data) |*scalar, i| {
2005 const res_bool = compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType(), target);2020 const res_bool = compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType(), mod);
2006 scalar.* = if (res_bool) Value.@"true" else Value.@"false";2021 scalar.* = if (res_bool) Value.@"true" else Value.@"false";
2007 }2022 }
2008 return Value.Tag.aggregate.create(allocator, result_data);2023 return Value.Tag.aggregate.create(allocator, result_data);
...@@ -2032,7 +2047,8 @@ pub const Value = extern union {...@@ -2032,7 +2047,8 @@ pub const Value = extern union {
2032 /// for `a`. This function must act *as if* `a` has been coerced to `ty`. This complication2047 /// for `a`. This function must act *as if* `a` has been coerced to `ty`. This complication
2033 /// is required in order to make generic function instantiation effecient - specifically2048 /// is required in order to make generic function instantiation effecient - specifically
2034 /// the insertion into the monomorphized function table.2049 /// the insertion into the monomorphized function table.
2035 pub fn eql(a: Value, b: Value, ty: Type, target: Target) bool {2050 pub fn eql(a: Value, b: Value, ty: Type, mod: *Module) bool {
2051 const target = mod.getTarget();
2036 const a_tag = a.tag();2052 const a_tag = a.tag();
2037 const b_tag = b.tag();2053 const b_tag = b.tag();
2038 if (a_tag == b_tag) switch (a_tag) {2054 if (a_tag == b_tag) switch (a_tag) {
...@@ -2052,31 +2068,31 @@ pub const Value = extern union {...@@ -2052,31 +2068,31 @@ pub const Value = extern union {
2052 const a_payload = a.castTag(.opt_payload).?.data;2068 const a_payload = a.castTag(.opt_payload).?.data;
2053 const b_payload = b.castTag(.opt_payload).?.data;2069 const b_payload = b.castTag(.opt_payload).?.data;
2054 var buffer: Type.Payload.ElemType = undefined;2070 var buffer: Type.Payload.ElemType = undefined;
2055 return eql(a_payload, b_payload, ty.optionalChild(&buffer), target);2071 return eql(a_payload, b_payload, ty.optionalChild(&buffer), mod);
2056 },2072 },
2057 .slice => {2073 .slice => {
2058 const a_payload = a.castTag(.slice).?.data;2074 const a_payload = a.castTag(.slice).?.data;
2059 const b_payload = b.castTag(.slice).?.data;2075 const b_payload = b.castTag(.slice).?.data;
2060 if (!eql(a_payload.len, b_payload.len, Type.usize, target)) return false;2076 if (!eql(a_payload.len, b_payload.len, Type.usize, mod)) return false;
20612077
2062 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;2078 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
2063 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);2079 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
20642080
2065 return eql(a_payload.ptr, b_payload.ptr, ptr_ty, target);2081 return eql(a_payload.ptr, b_payload.ptr, ptr_ty, mod);
2066 },2082 },
2067 .elem_ptr => {2083 .elem_ptr => {
2068 const a_payload = a.castTag(.elem_ptr).?.data;2084 const a_payload = a.castTag(.elem_ptr).?.data;
2069 const b_payload = b.castTag(.elem_ptr).?.data;2085 const b_payload = b.castTag(.elem_ptr).?.data;
2070 if (a_payload.index != b_payload.index) return false;2086 if (a_payload.index != b_payload.index) return false;
20712087
2072 return eql(a_payload.array_ptr, b_payload.array_ptr, ty, target);2088 return eql(a_payload.array_ptr, b_payload.array_ptr, ty, mod);
2073 },2089 },
2074 .field_ptr => {2090 .field_ptr => {
2075 const a_payload = a.castTag(.field_ptr).?.data;2091 const a_payload = a.castTag(.field_ptr).?.data;
2076 const b_payload = b.castTag(.field_ptr).?.data;2092 const b_payload = b.castTag(.field_ptr).?.data;
2077 if (a_payload.field_index != b_payload.field_index) return false;2093 if (a_payload.field_index != b_payload.field_index) return false;
20782094
2079 return eql(a_payload.container_ptr, b_payload.container_ptr, ty, target);2095 return eql(a_payload.container_ptr, b_payload.container_ptr, ty, mod);
2080 },2096 },
2081 .@"error" => {2097 .@"error" => {
2082 const a_name = a.castTag(.@"error").?.data.name;2098 const a_name = a.castTag(.@"error").?.data.name;
...@@ -2086,7 +2102,7 @@ pub const Value = extern union {...@@ -2086,7 +2102,7 @@ pub const Value = extern union {
2086 .eu_payload => {2102 .eu_payload => {
2087 const a_payload = a.castTag(.eu_payload).?.data;2103 const a_payload = a.castTag(.eu_payload).?.data;
2088 const b_payload = b.castTag(.eu_payload).?.data;2104 const b_payload = b.castTag(.eu_payload).?.data;
2089 return eql(a_payload, b_payload, ty.errorUnionPayload(), target);2105 return eql(a_payload, b_payload, ty.errorUnionPayload(), mod);
2090 },2106 },
2091 .eu_payload_ptr => @panic("TODO: Implement more pointer eql cases"),2107 .eu_payload_ptr => @panic("TODO: Implement more pointer eql cases"),
2092 .opt_payload_ptr => @panic("TODO: Implement more pointer eql cases"),2108 .opt_payload_ptr => @panic("TODO: Implement more pointer eql cases"),
...@@ -2104,7 +2120,7 @@ pub const Value = extern union {...@@ -2104,7 +2120,7 @@ pub const Value = extern union {
2104 const types = ty.tupleFields().types;2120 const types = ty.tupleFields().types;
2105 assert(types.len == a_field_vals.len);2121 assert(types.len == a_field_vals.len);
2106 for (types) |field_ty, i| {2122 for (types) |field_ty, i| {
2107 if (!eql(a_field_vals[i], b_field_vals[i], field_ty, target)) return false;2123 if (!eql(a_field_vals[i], b_field_vals[i], field_ty, mod)) return false;
2108 }2124 }
2109 return true;2125 return true;
2110 }2126 }
...@@ -2113,7 +2129,7 @@ pub const Value = extern union {...@@ -2113,7 +2129,7 @@ pub const Value = extern union {
2113 const fields = ty.structFields().values();2129 const fields = ty.structFields().values();
2114 assert(fields.len == a_field_vals.len);2130 assert(fields.len == a_field_vals.len);
2115 for (fields) |field, i| {2131 for (fields) |field, i| {
2116 if (!eql(a_field_vals[i], b_field_vals[i], field.ty, target)) return false;2132 if (!eql(a_field_vals[i], b_field_vals[i], field.ty, mod)) return false;
2117 }2133 }
2118 return true;2134 return true;
2119 }2135 }
...@@ -2122,7 +2138,7 @@ pub const Value = extern union {...@@ -2122,7 +2138,7 @@ pub const Value = extern union {
2122 for (a_field_vals) |a_elem, i| {2138 for (a_field_vals) |a_elem, i| {
2123 const b_elem = b_field_vals[i];2139 const b_elem = b_field_vals[i];
21242140
2125 if (!eql(a_elem, b_elem, elem_ty, target)) return false;2141 if (!eql(a_elem, b_elem, elem_ty, mod)) return false;
2126 }2142 }
2127 return true;2143 return true;
2128 },2144 },
...@@ -2132,7 +2148,7 @@ pub const Value = extern union {...@@ -2132,7 +2148,7 @@ pub const Value = extern union {
2132 switch (ty.containerLayout()) {2148 switch (ty.containerLayout()) {
2133 .Packed, .Extern => {2149 .Packed, .Extern => {
2134 const tag_ty = ty.unionTagTypeHypothetical();2150 const tag_ty = ty.unionTagTypeHypothetical();
2135 if (!a_union.tag.eql(b_union.tag, tag_ty, target)) {2151 if (!a_union.tag.eql(b_union.tag, tag_ty, mod)) {
2136 // In this case, we must disregard mismatching tags and compare2152 // In this case, we must disregard mismatching tags and compare
2137 // based on the in-memory bytes of the payloads.2153 // based on the in-memory bytes of the payloads.
2138 @panic("TODO comptime comparison of extern union values with mismatching tags");2154 @panic("TODO comptime comparison of extern union values with mismatching tags");
...@@ -2140,13 +2156,13 @@ pub const Value = extern union {...@@ -2140,13 +2156,13 @@ pub const Value = extern union {
2140 },2156 },
2141 .Auto => {2157 .Auto => {
2142 const tag_ty = ty.unionTagTypeHypothetical();2158 const tag_ty = ty.unionTagTypeHypothetical();
2143 if (!a_union.tag.eql(b_union.tag, tag_ty, target)) {2159 if (!a_union.tag.eql(b_union.tag, tag_ty, mod)) {
2144 return false;2160 return false;
2145 }2161 }
2146 },2162 },
2147 }2163 }
2148 const active_field_ty = ty.unionFieldType(a_union.tag, target);2164 const active_field_ty = ty.unionFieldType(a_union.tag, mod);
2149 return a_union.val.eql(b_union.val, active_field_ty, target);2165 return a_union.val.eql(b_union.val, active_field_ty, mod);
2150 },2166 },
2151 else => {},2167 else => {},
2152 } else if (a_tag == .null_value or b_tag == .null_value) {2168 } else if (a_tag == .null_value or b_tag == .null_value) {
...@@ -2171,7 +2187,7 @@ pub const Value = extern union {...@@ -2171,7 +2187,7 @@ pub const Value = extern union {
2171 var buf_b: ToTypeBuffer = undefined;2187 var buf_b: ToTypeBuffer = undefined;
2172 const a_type = a.toType(&buf_a);2188 const a_type = a.toType(&buf_a);
2173 const b_type = b.toType(&buf_b);2189 const b_type = b.toType(&buf_b);
2174 return a_type.eql(b_type, target);2190 return a_type.eql(b_type, mod);
2175 },2191 },
2176 .Enum => {2192 .Enum => {
2177 var buf_a: Payload.U64 = undefined;2193 var buf_a: Payload.U64 = undefined;
...@@ -2180,7 +2196,7 @@ pub const Value = extern union {...@@ -2180,7 +2196,7 @@ pub const Value = extern union {
2180 const b_val = b.enumToInt(ty, &buf_b);2196 const b_val = b.enumToInt(ty, &buf_b);
2181 var buf_ty: Type.Payload.Bits = undefined;2197 var buf_ty: Type.Payload.Bits = undefined;
2182 const int_ty = ty.intTagType(&buf_ty);2198 const int_ty = ty.intTagType(&buf_ty);
2183 return eql(a_val, b_val, int_ty, target);2199 return eql(a_val, b_val, int_ty, mod);
2184 },2200 },
2185 .Array, .Vector => {2201 .Array, .Vector => {
2186 const len = ty.arrayLen();2202 const len = ty.arrayLen();
...@@ -2189,9 +2205,9 @@ pub const Value = extern union {...@@ -2189,9 +2205,9 @@ pub const Value = extern union {
2189 var a_buf: ElemValueBuffer = undefined;2205 var a_buf: ElemValueBuffer = undefined;
2190 var b_buf: ElemValueBuffer = undefined;2206 var b_buf: ElemValueBuffer = undefined;
2191 while (i < len) : (i += 1) {2207 while (i < len) : (i += 1) {
2192 const a_elem = elemValueBuffer(a, i, &a_buf);2208 const a_elem = elemValueBuffer(a, mod, i, &a_buf);
2193 const b_elem = elemValueBuffer(b, i, &b_buf);2209 const b_elem = elemValueBuffer(b, mod, i, &b_buf);
2194 if (!eql(a_elem, b_elem, elem_ty, target)) return false;2210 if (!eql(a_elem, b_elem, elem_ty, mod)) return false;
2195 }2211 }
2196 return true;2212 return true;
2197 },2213 },
...@@ -2215,7 +2231,7 @@ pub const Value = extern union {...@@ -2215,7 +2231,7 @@ pub const Value = extern union {
2215 .base = .{ .tag = .opt_payload },2231 .base = .{ .tag = .opt_payload },
2216 .data = a,2232 .data = a,
2217 };2233 };
2218 return eql(Value.initPayload(&buffer.base), b, ty, target);2234 return eql(Value.initPayload(&buffer.base), b, ty, mod);
2219 }2235 }
2220 },2236 },
2221 else => {},2237 else => {},
...@@ -2225,7 +2241,7 @@ pub const Value = extern union {...@@ -2225,7 +2241,7 @@ pub const Value = extern union {
22252241
2226 /// This function is used by hash maps and so treats floating-point NaNs as equal2242 /// This function is used by hash maps and so treats floating-point NaNs as equal
2227 /// to each other, and not equal to other floating-point values.2243 /// to each other, and not equal to other floating-point values.
2228 pub fn hash(val: Value, ty: Type, hasher: *std.hash.Wyhash, target: Target) void {2244 pub fn hash(val: Value, ty: Type, hasher: *std.hash.Wyhash, mod: *Module) void {
2229 const zig_ty_tag = ty.zigTypeTag();2245 const zig_ty_tag = ty.zigTypeTag();
2230 std.hash.autoHash(hasher, zig_ty_tag);2246 std.hash.autoHash(hasher, zig_ty_tag);
2231 if (val.isUndef()) return;2247 if (val.isUndef()) return;
...@@ -2242,7 +2258,7 @@ pub const Value = extern union {...@@ -2242,7 +2258,7 @@ pub const Value = extern union {
22422258
2243 .Type => {2259 .Type => {
2244 var buf: ToTypeBuffer = undefined;2260 var buf: ToTypeBuffer = undefined;
2245 return val.toType(&buf).hashWithHasher(hasher, target);2261 return val.toType(&buf).hashWithHasher(hasher, mod);
2246 },2262 },
2247 .Float, .ComptimeFloat => {2263 .Float, .ComptimeFloat => {
2248 // Normalize the float here because this hash must match eql semantics.2264 // Normalize the float here because this hash must match eql semantics.
...@@ -2263,11 +2279,11 @@ pub const Value = extern union {...@@ -2263,11 +2279,11 @@ pub const Value = extern union {
2263 const slice = val.castTag(.slice).?.data;2279 const slice = val.castTag(.slice).?.data;
2264 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;2280 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
2265 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);2281 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
2266 hash(slice.ptr, ptr_ty, hasher, target);2282 hash(slice.ptr, ptr_ty, hasher, mod);
2267 hash(slice.len, Type.usize, hasher, target);2283 hash(slice.len, Type.usize, hasher, mod);
2268 },2284 },
22692285
2270 else => return hashPtr(val, hasher, target),2286 else => return hashPtr(val, hasher, mod.getTarget()),
2271 },2287 },
2272 .Array, .Vector => {2288 .Array, .Vector => {
2273 const len = ty.arrayLen();2289 const len = ty.arrayLen();
...@@ -2275,15 +2291,15 @@ pub const Value = extern union {...@@ -2275,15 +2291,15 @@ pub const Value = extern union {
2275 var index: usize = 0;2291 var index: usize = 0;
2276 var elem_value_buf: ElemValueBuffer = undefined;2292 var elem_value_buf: ElemValueBuffer = undefined;
2277 while (index < len) : (index += 1) {2293 while (index < len) : (index += 1) {
2278 const elem_val = val.elemValueBuffer(index, &elem_value_buf);2294 const elem_val = val.elemValueBuffer(mod, index, &elem_value_buf);
2279 elem_val.hash(elem_ty, hasher, target);2295 elem_val.hash(elem_ty, hasher, mod);
2280 }2296 }
2281 },2297 },
2282 .Struct => {2298 .Struct => {
2283 if (ty.isTupleOrAnonStruct()) {2299 if (ty.isTupleOrAnonStruct()) {
2284 const fields = ty.tupleFields();2300 const fields = ty.tupleFields();
2285 for (fields.values) |field_val, i| {2301 for (fields.values) |field_val, i| {
2286 field_val.hash(fields.types[i], hasher, target);2302 field_val.hash(fields.types[i], hasher, mod);
2287 }2303 }
2288 return;2304 return;
2289 }2305 }
...@@ -2292,13 +2308,13 @@ pub const Value = extern union {...@@ -2292,13 +2308,13 @@ pub const Value = extern union {
2292 switch (val.tag()) {2308 switch (val.tag()) {
2293 .empty_struct_value => {2309 .empty_struct_value => {
2294 for (fields) |field| {2310 for (fields) |field| {
2295 field.default_val.hash(field.ty, hasher, target);2311 field.default_val.hash(field.ty, hasher, mod);
2296 }2312 }
2297 },2313 },
2298 .aggregate => {2314 .aggregate => {
2299 const field_values = val.castTag(.aggregate).?.data;2315 const field_values = val.castTag(.aggregate).?.data;
2300 for (field_values) |field_val, i| {2316 for (field_values) |field_val, i| {
2301 field_val.hash(fields[i].ty, hasher, target);2317 field_val.hash(fields[i].ty, hasher, mod);
2302 }2318 }
2303 },2319 },
2304 else => unreachable,2320 else => unreachable,
...@@ -2310,7 +2326,7 @@ pub const Value = extern union {...@@ -2310,7 +2326,7 @@ pub const Value = extern union {
2310 const sub_val = payload.data;2326 const sub_val = payload.data;
2311 var buffer: Type.Payload.ElemType = undefined;2327 var buffer: Type.Payload.ElemType = undefined;
2312 const sub_ty = ty.optionalChild(&buffer);2328 const sub_ty = ty.optionalChild(&buffer);
2313 sub_val.hash(sub_ty, hasher, target);2329 sub_val.hash(sub_ty, hasher, mod);
2314 } else {2330 } else {
2315 std.hash.autoHash(hasher, false); // non-null2331 std.hash.autoHash(hasher, false); // non-null
2316 }2332 }
...@@ -2319,14 +2335,14 @@ pub const Value = extern union {...@@ -2319,14 +2335,14 @@ pub const Value = extern union {
2319 if (val.tag() == .@"error") {2335 if (val.tag() == .@"error") {
2320 std.hash.autoHash(hasher, false); // error2336 std.hash.autoHash(hasher, false); // error
2321 const sub_ty = ty.errorUnionSet();2337 const sub_ty = ty.errorUnionSet();
2322 val.hash(sub_ty, hasher, target);2338 val.hash(sub_ty, hasher, mod);
2323 return;2339 return;
2324 }2340 }
23252341
2326 if (val.castTag(.eu_payload)) |payload| {2342 if (val.castTag(.eu_payload)) |payload| {
2327 std.hash.autoHash(hasher, true); // payload2343 std.hash.autoHash(hasher, true); // payload
2328 const sub_ty = ty.errorUnionPayload();2344 const sub_ty = ty.errorUnionPayload();
2329 payload.data.hash(sub_ty, hasher, target);2345 payload.data.hash(sub_ty, hasher, mod);
2330 return;2346 return;
2331 } else unreachable;2347 } else unreachable;
2332 },2348 },
...@@ -2339,15 +2355,15 @@ pub const Value = extern union {...@@ -2339,15 +2355,15 @@ pub const Value = extern union {
2339 .Enum => {2355 .Enum => {
2340 var enum_space: Payload.U64 = undefined;2356 var enum_space: Payload.U64 = undefined;
2341 const int_val = val.enumToInt(ty, &enum_space);2357 const int_val = val.enumToInt(ty, &enum_space);
2342 hashInt(int_val, hasher, target);2358 hashInt(int_val, hasher, mod.getTarget());
2343 },2359 },
2344 .Union => {2360 .Union => {
2345 const union_obj = val.cast(Payload.Union).?.data;2361 const union_obj = val.cast(Payload.Union).?.data;
2346 if (ty.unionTagType()) |tag_ty| {2362 if (ty.unionTagType()) |tag_ty| {
2347 union_obj.tag.hash(tag_ty, hasher, target);2363 union_obj.tag.hash(tag_ty, hasher, mod);
2348 }2364 }
2349 const active_field_ty = ty.unionFieldType(union_obj.tag, target);2365 const active_field_ty = ty.unionFieldType(union_obj.tag, mod);
2350 union_obj.val.hash(active_field_ty, hasher, target);2366 union_obj.val.hash(active_field_ty, hasher, mod);
2351 },2367 },
2352 .Fn => {2368 .Fn => {
2353 const func: *Module.Fn = val.castTag(.function).?.data;2369 const func: *Module.Fn = val.castTag(.function).?.data;
...@@ -2372,30 +2388,30 @@ pub const Value = extern union {...@@ -2372,30 +2388,30 @@ pub const Value = extern union {
23722388
2373 pub const ArrayHashContext = struct {2389 pub const ArrayHashContext = struct {
2374 ty: Type,2390 ty: Type,
2375 target: Target,2391 mod: *Module,
23762392
2377 pub fn hash(self: @This(), val: Value) u32 {2393 pub fn hash(self: @This(), val: Value) u32 {
2378 const other_context: HashContext = .{ .ty = self.ty, .target = self.target };2394 const other_context: HashContext = .{ .ty = self.ty, .mod = self.mod };
2379 return @truncate(u32, other_context.hash(val));2395 return @truncate(u32, other_context.hash(val));
2380 }2396 }
2381 pub fn eql(self: @This(), a: Value, b: Value, b_index: usize) bool {2397 pub fn eql(self: @This(), a: Value, b: Value, b_index: usize) bool {
2382 _ = b_index;2398 _ = b_index;
2383 return a.eql(b, self.ty, self.target);2399 return a.eql(b, self.ty, self.mod);
2384 }2400 }
2385 };2401 };
23862402
2387 pub const HashContext = struct {2403 pub const HashContext = struct {
2388 ty: Type,2404 ty: Type,
2389 target: Target,2405 mod: *Module,
23902406
2391 pub fn hash(self: @This(), val: Value) u64 {2407 pub fn hash(self: @This(), val: Value) u64 {
2392 var hasher = std.hash.Wyhash.init(0);2408 var hasher = std.hash.Wyhash.init(0);
2393 val.hash(self.ty, &hasher, self.target);2409 val.hash(self.ty, &hasher, self.mod);
2394 return hasher.final();2410 return hasher.final();
2395 }2411 }
23962412
2397 pub fn eql(self: @This(), a: Value, b: Value) bool {2413 pub fn eql(self: @This(), a: Value, b: Value) bool {
2398 return a.eql(b, self.ty, self.target);2414 return a.eql(b, self.ty, self.mod);
2399 }2415 }
2400 };2416 };
24012417
...@@ -2434,9 +2450,9 @@ pub const Value = extern union {...@@ -2434,9 +2450,9 @@ pub const Value = extern union {
2434 /// Gets the decl referenced by this pointer. If the pointer does not point2450 /// Gets the decl referenced by this pointer. If the pointer does not point
2435 /// to a decl, or if it points to some part of a decl (like field_ptr or element_ptr),2451 /// to a decl, or if it points to some part of a decl (like field_ptr or element_ptr),
2436 /// this function returns null.2452 /// this function returns null.
2437 pub fn pointerDecl(val: Value) ?*Module.Decl {2453 pub fn pointerDecl(val: Value) ?Module.Decl.Index {
2438 return switch (val.tag()) {2454 return switch (val.tag()) {
2439 .decl_ref_mut => val.castTag(.decl_ref_mut).?.data.decl,2455 .decl_ref_mut => val.castTag(.decl_ref_mut).?.data.decl_index,
2440 .extern_fn => val.castTag(.extern_fn).?.data.owner_decl,2456 .extern_fn => val.castTag(.extern_fn).?.data.owner_decl,
2441 .function => val.castTag(.function).?.data.owner_decl,2457 .function => val.castTag(.function).?.data.owner_decl,
2442 .variable => val.castTag(.variable).?.data.owner_decl,2458 .variable => val.castTag(.variable).?.data.owner_decl,
...@@ -2462,7 +2478,7 @@ pub const Value = extern union {...@@ -2462,7 +2478,7 @@ pub const Value = extern union {
2462 .function,2478 .function,
2463 .variable,2479 .variable,
2464 => {2480 => {
2465 const decl: *Module.Decl = ptr_val.pointerDecl().?;2481 const decl: Module.Decl.Index = ptr_val.pointerDecl().?;
2466 std.hash.autoHash(hasher, decl);2482 std.hash.autoHash(hasher, decl);
2467 },2483 },
24682484
...@@ -2505,53 +2521,6 @@ pub const Value = extern union {...@@ -2505,53 +2521,6 @@ pub const Value = extern union {
2505 }2521 }
2506 }2522 }
25072523
2508 pub fn markReferencedDeclsAlive(val: Value) void {
2509 switch (val.tag()) {
2510 .decl_ref_mut => return val.castTag(.decl_ref_mut).?.data.decl.markAlive(),
2511 .extern_fn => return val.castTag(.extern_fn).?.data.owner_decl.markAlive(),
2512 .function => return val.castTag(.function).?.data.owner_decl.markAlive(),
2513 .variable => return val.castTag(.variable).?.data.owner_decl.markAlive(),
2514 .decl_ref => return val.cast(Payload.Decl).?.data.markAlive(),
2515
2516 .repeated,
2517 .eu_payload,
2518 .opt_payload,
2519 .empty_array_sentinel,
2520 => return markReferencedDeclsAlive(val.cast(Payload.SubValue).?.data),
2521
2522 .eu_payload_ptr,
2523 .opt_payload_ptr,
2524 => return markReferencedDeclsAlive(val.cast(Payload.PayloadPtr).?.data.container_ptr),
2525
2526 .slice => {
2527 const slice = val.cast(Payload.Slice).?.data;
2528 markReferencedDeclsAlive(slice.ptr);
2529 markReferencedDeclsAlive(slice.len);
2530 },
2531
2532 .elem_ptr => {
2533 const elem_ptr = val.cast(Payload.ElemPtr).?.data;
2534 return markReferencedDeclsAlive(elem_ptr.array_ptr);
2535 },
2536 .field_ptr => {
2537 const field_ptr = val.cast(Payload.FieldPtr).?.data;
2538 return markReferencedDeclsAlive(field_ptr.container_ptr);
2539 },
2540 .aggregate => {
2541 for (val.castTag(.aggregate).?.data) |field_val| {
2542 markReferencedDeclsAlive(field_val);
2543 }
2544 },
2545 .@"union" => {
2546 const data = val.cast(Payload.Union).?.data;
2547 markReferencedDeclsAlive(data.tag);
2548 markReferencedDeclsAlive(data.val);
2549 },
2550
2551 else => {},
2552 }
2553 }
2554
2555 pub fn slicePtr(val: Value) Value {2524 pub fn slicePtr(val: Value) Value {
2556 return switch (val.tag()) {2525 return switch (val.tag()) {
2557 .slice => val.castTag(.slice).?.data.ptr,2526 .slice => val.castTag(.slice).?.data.ptr,
...@@ -2561,11 +2530,12 @@ pub const Value = extern union {...@@ -2561,11 +2530,12 @@ pub const Value = extern union {
2561 };2530 };
2562 }2531 }
25632532
2564 pub fn sliceLen(val: Value, target: Target) u64 {2533 pub fn sliceLen(val: Value, mod: *Module) u64 {
2565 return switch (val.tag()) {2534 return switch (val.tag()) {
2566 .slice => val.castTag(.slice).?.data.len.toUnsignedInt(target),2535 .slice => val.castTag(.slice).?.data.len.toUnsignedInt(mod.getTarget()),
2567 .decl_ref => {2536 .decl_ref => {
2568 const decl = val.castTag(.decl_ref).?.data;2537 const decl_index = val.castTag(.decl_ref).?.data;
2538 const decl = mod.declPtr(decl_index);
2569 if (decl.ty.zigTypeTag() == .Array) {2539 if (decl.ty.zigTypeTag() == .Array) {
2570 return decl.ty.arrayLen();2540 return decl.ty.arrayLen();
2571 } else {2541 } else {
...@@ -2599,18 +2569,19 @@ pub const Value = extern union {...@@ -2599,18 +2569,19 @@ pub const Value = extern union {
25992569
2600 /// Asserts the value is a single-item pointer to an array, or an array,2570 /// Asserts the value is a single-item pointer to an array, or an array,
2601 /// or an unknown-length pointer, and returns the element value at the index.2571 /// or an unknown-length pointer, and returns the element value at the index.
2602 pub fn elemValue(val: Value, arena: Allocator, index: usize) !Value {2572 pub fn elemValue(val: Value, mod: *Module, arena: Allocator, index: usize) !Value {
2603 return elemValueAdvanced(val, index, arena, undefined);2573 return elemValueAdvanced(val, mod, index, arena, undefined);
2604 }2574 }
26052575
2606 pub const ElemValueBuffer = Payload.U64;2576 pub const ElemValueBuffer = Payload.U64;
26072577
2608 pub fn elemValueBuffer(val: Value, index: usize, buffer: *ElemValueBuffer) Value {2578 pub fn elemValueBuffer(val: Value, mod: *Module, index: usize, buffer: *ElemValueBuffer) Value {
2609 return elemValueAdvanced(val, index, null, buffer) catch unreachable;2579 return elemValueAdvanced(val, mod, index, null, buffer) catch unreachable;
2610 }2580 }
26112581
2612 pub fn elemValueAdvanced(2582 pub fn elemValueAdvanced(
2613 val: Value,2583 val: Value,
2584 mod: *Module,
2614 index: usize,2585 index: usize,
2615 arena: ?Allocator,2586 arena: ?Allocator,
2616 buffer: *ElemValueBuffer,2587 buffer: *ElemValueBuffer,
...@@ -2643,13 +2614,13 @@ pub const Value = extern union {...@@ -2643,13 +2614,13 @@ pub const Value = extern union {
2643 .repeated => return val.castTag(.repeated).?.data,2614 .repeated => return val.castTag(.repeated).?.data,
26442615
2645 .aggregate => return val.castTag(.aggregate).?.data[index],2616 .aggregate => return val.castTag(.aggregate).?.data[index],
2646 .slice => return val.castTag(.slice).?.data.ptr.elemValueAdvanced(index, arena, buffer),2617 .slice => return val.castTag(.slice).?.data.ptr.elemValueAdvanced(mod, index, arena, buffer),
26472618
2648 .decl_ref => return val.castTag(.decl_ref).?.data.val.elemValueAdvanced(index, arena, buffer),2619 .decl_ref => return mod.declPtr(val.castTag(.decl_ref).?.data).val.elemValueAdvanced(mod, index, arena, buffer),
2649 .decl_ref_mut => return val.castTag(.decl_ref_mut).?.data.decl.val.elemValueAdvanced(index, arena, buffer),2620 .decl_ref_mut => return mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val.elemValueAdvanced(mod, index, arena, buffer),
2650 .elem_ptr => {2621 .elem_ptr => {
2651 const data = val.castTag(.elem_ptr).?.data;2622 const data = val.castTag(.elem_ptr).?.data;
2652 return data.array_ptr.elemValueAdvanced(index + data.index, arena, buffer);2623 return data.array_ptr.elemValueAdvanced(mod, index + data.index, arena, buffer);
2653 },2624 },
26542625
2655 // The child type of arrays which have only one possible value need2626 // The child type of arrays which have only one possible value need
...@@ -2661,18 +2632,24 @@ pub const Value = extern union {...@@ -2661,18 +2632,24 @@ pub const Value = extern union {
2661 }2632 }
26622633
2663 // Asserts that the provided start/end are in-bounds.2634 // Asserts that the provided start/end are in-bounds.
2664 pub fn sliceArray(val: Value, arena: Allocator, start: usize, end: usize) error{OutOfMemory}!Value {2635 pub fn sliceArray(
2636 val: Value,
2637 mod: *Module,
2638 arena: Allocator,
2639 start: usize,
2640 end: usize,
2641 ) error{OutOfMemory}!Value {
2665 return switch (val.tag()) {2642 return switch (val.tag()) {
2666 .empty_array_sentinel => if (start == 0 and end == 1) val else Value.initTag(.empty_array),2643 .empty_array_sentinel => if (start == 0 and end == 1) val else Value.initTag(.empty_array),
2667 .bytes => Tag.bytes.create(arena, val.castTag(.bytes).?.data[start..end]),2644 .bytes => Tag.bytes.create(arena, val.castTag(.bytes).?.data[start..end]),
2668 .aggregate => Tag.aggregate.create(arena, val.castTag(.aggregate).?.data[start..end]),2645 .aggregate => Tag.aggregate.create(arena, val.castTag(.aggregate).?.data[start..end]),
2669 .slice => sliceArray(val.castTag(.slice).?.data.ptr, arena, start, end),2646 .slice => sliceArray(val.castTag(.slice).?.data.ptr, mod, arena, start, end),
26702647
2671 .decl_ref => sliceArray(val.castTag(.decl_ref).?.data.val, arena, start, end),2648 .decl_ref => sliceArray(mod.declPtr(val.castTag(.decl_ref).?.data).val, mod, arena, start, end),
2672 .decl_ref_mut => sliceArray(val.castTag(.decl_ref_mut).?.data.decl.val, arena, start, end),2649 .decl_ref_mut => sliceArray(mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val, mod, arena, start, end),
2673 .elem_ptr => blk: {2650 .elem_ptr => blk: {
2674 const elem_ptr = val.castTag(.elem_ptr).?.data;2651 const elem_ptr = val.castTag(.elem_ptr).?.data;
2675 break :blk sliceArray(elem_ptr.array_ptr, arena, start + elem_ptr.index, end + elem_ptr.index);2652 break :blk sliceArray(elem_ptr.array_ptr, mod, arena, start + elem_ptr.index, end + elem_ptr.index);
2676 },2653 },
26772654
2678 .repeated,2655 .repeated,
...@@ -2718,7 +2695,13 @@ pub const Value = extern union {...@@ -2718,7 +2695,13 @@ pub const Value = extern union {
2718 }2695 }
27192696
2720 /// Returns a pointer to the element value at the index.2697 /// Returns a pointer to the element value at the index.
2721 pub fn elemPtr(val: Value, ty: Type, arena: Allocator, index: usize, target: Target) Allocator.Error!Value {2698 pub fn elemPtr(
2699 val: Value,
2700 ty: Type,
2701 arena: Allocator,
2702 index: usize,
2703 mod: *Module,
2704 ) Allocator.Error!Value {
2722 const elem_ty = ty.elemType2();2705 const elem_ty = ty.elemType2();
2723 const ptr_val = switch (val.tag()) {2706 const ptr_val = switch (val.tag()) {
2724 .slice => val.castTag(.slice).?.data.ptr,2707 .slice => val.castTag(.slice).?.data.ptr,
...@@ -2727,7 +2710,7 @@ pub const Value = extern union {...@@ -2727,7 +2710,7 @@ pub const Value = extern union {
27272710
2728 if (ptr_val.tag() == .elem_ptr) {2711 if (ptr_val.tag() == .elem_ptr) {
2729 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;2712 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
2730 if (elem_ptr.elem_ty.eql(elem_ty, target)) {2713 if (elem_ptr.elem_ty.eql(elem_ty, mod)) {
2731 return Tag.elem_ptr.create(arena, .{2714 return Tag.elem_ptr.create(arena, .{
2732 .array_ptr = elem_ptr.array_ptr,2715 .array_ptr = elem_ptr.array_ptr,
2733 .elem_ty = elem_ptr.elem_ty,2716 .elem_ty = elem_ptr.elem_ty,
...@@ -5059,7 +5042,7 @@ pub const Value = extern union {...@@ -5059,7 +5042,7 @@ pub const Value = extern union {
50595042
5060 pub const Decl = struct {5043 pub const Decl = struct {
5061 base: Payload,5044 base: Payload,
5062 data: *Module.Decl,5045 data: Module.Decl.Index,
5063 };5046 };
50645047
5065 pub const Variable = struct {5048 pub const Variable = struct {
...@@ -5079,7 +5062,7 @@ pub const Value = extern union {...@@ -5079,7 +5062,7 @@ pub const Value = extern union {
5079 data: Data,5062 data: Data,
50805063
5081 pub const Data = struct {5064 pub const Data = struct {
5082 decl: *Module.Decl,5065 decl_index: Module.Decl.Index,
5083 runtime_index: u32,5066 runtime_index: u32,
5084 };5067 };
5085 };5068 };
...@@ -5215,7 +5198,7 @@ pub const Value = extern union {...@@ -5215,7 +5198,7 @@ pub const Value = extern union {
52155198
5216 base: Payload = .{ .tag = base_tag },5199 base: Payload = .{ .tag = base_tag },
5217 data: struct {5200 data: struct {
5218 decl: *Module.Decl,5201 decl_index: Module.Decl.Index,
5219 /// 0 means ABI-aligned.5202 /// 0 means ABI-aligned.
5220 alignment: u16,5203 alignment: u16,
5221 },5204 },