| author | |
| committer | |
| log | bd5831ce0e033662fed1adf98e81e7d058c6f883 |
| tree | 6d7f915268e23ae56e33a713b1be3ac7560a949e |
| parent | 1a1b5ee264d8b2219c34d53cc9602692e6d2ba24 |
| parent | 31758f79db2c9e1122fd40bdda2243311830a5d4 |
| signature | Signed by PGP key 4AEE18F83AFDEB23 |
stage2: use indexes for Decl objects34 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 | } |
| 914 | 914 | ||
| 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 @@ | ||
| 1 | const std = @import("std.zig"); | ||
| 2 | const assert = std.debug.assert; | ||
| 3 | const testing = std.testing; | ||
| 4 | const 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. | ||
| 77 | pub 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 | |||
| 377 | test "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 | |||
| 386 | fn 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. | ||
| 466 | fn 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 |
| 29 | pub const PriorityQueue = @import("priority_queue.zig").PriorityQueue; | 29 | pub const PriorityQueue = @import("priority_queue.zig").PriorityQueue; |
| 30 | pub const PriorityDequeue = @import("priority_dequeue.zig").PriorityDequeue; | 30 | pub const PriorityDequeue = @import("priority_dequeue.zig").PriorityDequeue; |
| 31 | pub const Progress = @import("Progress.zig"); | 31 | pub const Progress = @import("Progress.zig"); |
| 32 | pub const SegmentedList = @import("segmented_list.zig").SegmentedList; | ||
| 32 | pub const SemanticVersion = @import("SemanticVersion.zig"); | 33 | pub const SemanticVersion = @import("SemanticVersion.zig"); |
| 33 | pub const SinglyLinkedList = @import("linked_list.zig").SinglyLinkedList; | 34 | pub const SinglyLinkedList = @import("linked_list.zig").SinglyLinkedList; |
| 34 | pub const StaticBitSet = bit_set.StaticBitSet; | 35 | pub 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 { |
| 191 | 191 | ||
| 192 | const Job = union(enum) { | 192 | const 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 determined | 200 | /// 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 disk | 203 | /// The file that was loaded with `@embedFile` has changed on disk |
| 204 | /// and has been re-loaded into memory. All Decls that depend on it | 204 | /// 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 the | 207 | /// 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, |
| 212 | 212 | ||
| ... | @@ -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; |
| 2114 | 2115 | ||
| 2115 | try module.clearDecl(decl, null); | 2116 | try module.clearDecl(decl_index, null); |
| 2116 | 2117 | ||
| 2117 | if (is_anon) { | 2118 | if (is_anon) { |
| 2118 | decl.destroy(module); | 2119 | module.destroyDecl(decl_index); |
| 2119 | } | 2120 | } |
| 2120 | } | 2121 | } |
| 2121 | 2122 | ||
| ... | @@ -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 cannot | 2445 | // 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); |
| 2574 | 2580 | ||
| 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( |
| 2708 | 2715 | ||
| 2709 | fn processOneJob(comp: *Compilation, job: Job) !void { | 2716 | fn 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 | } | ||
| 2737 | 2721 | ||
| 2738 | // Instead of sending this decl to the linker, we actually will delete it | 2722 | 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(); | ||
| 2800 | 2771 | ||
| 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(); | ||
| 2808 | 2815 | ||
| 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"); |
| 2816 | 2832 | ||
| 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"); |
| 2839 | 2855 | ||
| ... | @@ -2842,9 +2858,10 @@ fn processOneJob(comp: *Compilation, job: Job) !void { | ... | @@ -2842,9 +2858,10 @@ fn processOneJob(comp: *Compilation, job: Job) !void { |
| 2842 | 2858 | ||
| 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; |
| 3474 | 3491 | ||
| 3475 | const src_loc: Module.SrcLoc = embed_file.owner_decl.srcLoc(); | 3492 | const src_loc: Module.SrcLoc = mod.declPtr(embed_file.owner_decl).srcLoc(); |
| 3476 | 3493 | ||
| 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. |
| 50 | local_zir_cache: Compilation.Directory, | 50 | local_zir_cache: Compilation.Directory, |
| 51 | /// It's rare for a decl to be exported, so we save memory by having a sparse | 51 | /// 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 itself | 53 | /// 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. |
| 55 | decl_exports: std.AutoArrayHashMapUnmanaged(*Decl, []*Export) = .{}, | 55 | decl_exports: std.AutoArrayHashMapUnmanaged(Decl.Index, []*Export) = .{}, |
| 56 | /// This models the Decls that perform exports, so that `decl_exports` can be updated when a Decl | 56 | /// 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 that | 57 | /// 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. |
| 60 | export_owners: std.AutoArrayHashMapUnmanaged(*Decl, []*Export) = .{}, | 60 | export_owners: std.AutoArrayHashMapUnmanaged(Decl.Index, []*Export) = .{}, |
| 61 | /// The set of all the Zig source files in the Module. We keep track of this in order | 61 | /// 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 when | 62 | /// 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. |
| 92 | failed_decls: std.AutoArrayHashMapUnmanaged(*Decl, *ErrorMsg) = .{}, | 92 | failed_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. |
| 95 | compile_log_decls: std.AutoArrayHashMapUnmanaged(*Decl, i32) = .{}, | 95 | compile_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. |
| 98 | failed_files: std.AutoArrayHashMapUnmanaged(*File, ?*ErrorMsg) = .{}, | 98 | failed_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. |
| 103 | failed_exports: std.AutoArrayHashMapUnmanaged(*Export, *ErrorMsg) = .{}, | 103 | failed_exports: std.AutoArrayHashMapUnmanaged(*Export, *ErrorMsg) = .{}, |
| 104 | 104 | ||
| 105 | next_anon_name_index: usize = 0, | ||
| 106 | |||
| 107 | /// Candidates for deletion. After a semantic analysis update completes, this list | 105 | /// 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. |
| 109 | deletion_set: std.AutoArrayHashMapUnmanaged(*Decl, void) = .{}, | 107 | deletion_set: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{}, |
| 110 | 108 | ||
| 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) = .{}, |
| 137 | 135 | ||
| 138 | emit_h: ?*GlobalEmitH, | 136 | emit_h: ?*GlobalEmitH, |
| 139 | 137 | ||
| 140 | test_functions: std.AutoArrayHashMapUnmanaged(*Decl, void) = .{}, | 138 | test_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. | ||
| 150 | allocated_decls: std.SegmentedList(Decl, 0) = .{}, | ||
| 151 | /// When a Decl object is freed from `allocated_decls`, it is pushed into this stack. | ||
| 152 | decls_free_list: std.ArrayListUnmanaged(Decl.Index) = .{}, | ||
| 141 | 153 | ||
| 142 | const MonomorphedFuncsSet = std.HashMapUnmanaged( | 154 | const 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 | ); |
| 174 | 186 | ||
| 175 | pub const MemoizedCall = struct { | 187 | pub const MemoizedCall = struct { |
| 176 | target: std.Target, | 188 | module: *Module, |
| 177 | 189 | ||
| 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` that | 222 | // 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 | } |
| 215 | 227 | ||
| 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 for | 243 | /// 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 has | 244 | /// 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 | }; |
| 238 | 258 | ||
| 239 | pub const ErrorInt = u32; | 259 | pub 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 calls | 268 | /// 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 | }, |
| 261 | 281 | ||
| 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 | }; |
| 270 | 291 | ||
| 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. | ||
| 273 | pub const DeclPlusEmitH = struct { | ||
| 274 | decl: Decl, | ||
| 275 | emit_h: EmitH, | ||
| 276 | }; | ||
| 277 | |||
| 278 | pub const CaptureScope = struct { | 292 | pub const CaptureScope = struct { |
| 279 | parent: ?*CaptureScope, | 293 | parent: ?*CaptureScope, |
| 280 | 294 | ||
| ... | @@ -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 = .{}, |
| 460 | 474 | ||
| 461 | pub const DepsTable = std.AutoArrayHashMapUnmanaged(*Decl, void); | 475 | pub const Index = enum(u32) { |
| 462 | 476 | _, | |
| 463 | pub fn clearName(decl: *Decl, gpa: Allocator) void { | ||
| 464 | gpa.free(mem.sliceTo(decl.name, 0)); | ||
| 465 | decl.name = undefined; | ||
| 466 | } | ||
| 467 | 477 | ||
| 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 | } |
| 492 | 503 | ||
| 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 | } |
| 575 | 586 | ||
| 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 | } |
| 624 | 628 | ||
| 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 | } |
| 629 | 633 | ||
| 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 | } |
| 634 | 638 | ||
| 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 | } |
| 641 | 645 | ||
| ... | @@ -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 | } |
| 668 | 671 | ||
| ... | @@ -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 | } |
| 678 | 680 | ||
| ... | @@ -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 | } |
| 687 | 688 | ||
| ... | @@ -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 | } |
| 696 | 696 | ||
| 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 | } |
| 705 | 704 | ||
| ... | @@ -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 | }, |
| 736 | 731 | ||
| ... | @@ -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 | } |
| 759 | 754 | ||
| 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 | } |
| 769 | 758 | ||
| 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 | } |
| 773 | 762 | ||
| ... | @@ -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 | }; |
| 804 | 783 | ||
| 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. |
| 811 | pub const ErrorSet = struct { | 790 | pub 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 { |
| 819 | 798 | ||
| 820 | pub const NameMap = std.StringArrayHashMapUnmanaged(void); | 799 | pub const NameMap = std.StringArrayHashMapUnmanaged(void); |
| 821 | 800 | ||
| 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 }; |
| 844 | 824 | ||
| 845 | /// Represents the data that a struct declaration provides. | 825 | /// Represents the data that a struct declaration provides. |
| 846 | pub const Struct = struct { | 826 | pub 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 | }; |
| 902 | 882 | ||
| 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 | } |
| 906 | 886 | ||
| 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 | } |
| 914 | 895 | ||
| 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. |
| 1014 | pub const EnumSimple = struct { | 996 | pub 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, | ||
| 1021 | 1003 | ||
| 1022 | pub const NameMap = EnumFull.NameMap; | 1004 | pub const NameMap = EnumFull.NameMap; |
| 1023 | 1005 | ||
| 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. |
| 1036 | pub const EnumNumbered = struct { | 1019 | pub 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, | ||
| 1050 | 1033 | ||
| 1051 | pub const NameMap = EnumFull.NameMap; | 1034 | pub const NameMap = EnumFull.NameMap; |
| 1052 | pub const ValueMap = EnumFull.ValueMap; | 1035 | pub const ValueMap = EnumFull.ValueMap; |
| 1053 | 1036 | ||
| 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. |
| 1065 | pub const EnumFull = struct { | 1049 | pub 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 it | 1065 | /// true if zig inferred this tag type, false if user specified it |
| 1082 | tag_ty_inferred: bool, | 1066 | tag_ty_inferred: bool, |
| 1083 | 1067 | ||
| 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); |
| 1086 | 1070 | ||
| 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 | }; |
| 1095 | 1080 | ||
| 1096 | pub const Union = struct { | 1081 | pub 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 memory | 1083 | /// 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 { |
| 1145 | 1130 | ||
| 1146 | pub const Fields = std.StringArrayHashMapUnmanaged(Field); | 1131 | pub const Fields = std.StringArrayHashMapUnmanaged(Field); |
| 1147 | 1132 | ||
| 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 | } |
| 1151 | 1136 | ||
| 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 | } |
| 1159 | 1145 | ||
| 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 { |
| 1348 | 1335 | ||
| 1349 | pub const Opaque = struct { | 1336 | pub 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, | ||
| 1356 | 1343 | ||
| 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 | } |
| 1364 | 1352 | ||
| 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 | }; |
| 1369 | 1357 | ||
| ... | @@ -1371,7 +1359,7 @@ pub const Opaque = struct { | ... | @@ -1371,7 +1359,7 @@ pub const Opaque = struct { |
| 1371 | /// arena allocator. | 1359 | /// arena allocator. |
| 1372 | pub const ExternFn = struct { | 1360 | pub 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. |
| 1390 | pub const Fn = struct { | 1378 | pub 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, and | 1386 | /// 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, | ||
| 1411 | 1399 | ||
| 1412 | /// Prefer to use `getParamName` to access this because of the future improvement | 1400 | /// 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 | } |
| 1539 | 1527 | ||
| 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 { |
| 1556 | pub const Var = struct { | 1545 | pub const Var = struct { |
| 1557 | /// if is_extern == true this is undefined | 1546 | /// if is_extern == true this is undefined |
| 1558 | init: Value, | 1547 | init: Value, |
| 1559 | owner_decl: *Decl, | 1548 | owner_decl: Decl.Index, |
| 1560 | 1549 | ||
| 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 | }; |
| 1577 | 1566 | ||
| 1578 | pub const DeclAdapter = struct { | 1567 | pub 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 | } |
| 1583 | 1574 | ||
| 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) = .{}, |
| 1603 | 1594 | ||
| 1604 | anon_decls: std.AutoArrayHashMapUnmanaged(*Decl, void) = .{}, | 1595 | anon_decls: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{}, |
| 1605 | 1596 | ||
| 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) = .{}, |
| 1610 | 1601 | ||
| 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 | } |
| 1616 | 1609 | ||
| 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 | }; |
| 1623 | 1619 | ||
| ... | @@ -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 = .{}; |
| 1639 | 1635 | ||
| 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); |
| 1644 | 1640 | ||
| 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; |
| 1658 | 1654 | ||
| ... | @@ -1669,13 +1665,13 @@ pub const Namespace = struct { | ... | @@ -1669,13 +1665,13 @@ pub const Namespace = struct { |
| 1669 | 1665 | ||
| 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); |
| 1675 | 1671 | ||
| 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); |
| 1681 | 1677 | ||
| ... | @@ -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 | } |
| 1722 | 1722 | ||
| 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 | }; |
| 1727 | 1727 | ||
| 1728 | pub const File = struct { | 1728 | pub 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, | ||
| 1754 | 1754 | ||
| 1755 | /// Used by change detection algorithm, after astgen, contains the | 1755 | /// 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 the | 1758 | /// 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) = .{}, |
| 1762 | 1762 | ||
| 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 ZIR | 1764 | /// 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 file | 1933 | /// 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, |
| 1936 | 1936 | ||
| 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 | } |
| 2781 | 2782 | ||
| ... | @@ -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 | |||
| 2836 | pub 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 | |||
| 2867 | pub 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. | ||
| 2872 | pub 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 | } |
| 2831 | 2878 | ||
| 2832 | fn freeExportList(gpa: Allocator, export_list: []*Export) void { | 2879 | fn 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 Namespace | 3277 | // 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 concurrent | 3278 | // 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 succeeded | 3288 | // 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 to | 3289 | // 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_index | 3298 | /// * Decl.zir_index |
| 3252 | /// * Fn.zir_body_inst | 3299 | /// * Fn.zir_body_inst |
| 3253 | /// * Decl.zir_decl_index | 3300 | /// * Decl.zir_decl_index |
| 3254 | fn updateZirRefs(gpa: Allocator, file: *File, old_zir: Zir) !void { | 3301 | fn 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; |
| 3256 | 3304 | ||
| 3257 | // Maps from old ZIR to new ZIR, struct_decl, enum_decl, etc. Any instruction which | 3305 | // 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 populating | 3316 | // Walk the Decl graph, updating ZIR indexes, strings, and populating |
| 3269 | // the deleted and outdated lists. | 3317 | // the deleted and outdated lists. |
| 3270 | 3318 | ||
| 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); |
| 3273 | 3321 | ||
| 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); |
| 3276 | 3324 | ||
| 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); |
| 3283 | 3331 | ||
| 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 need | 3334 | // 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-generated | 3336 | // 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 { |
| 3314 | 3363 | ||
| 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 | } |
| 3321 | 3370 | ||
| 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 | } |
| 3328 | 3377 | ||
| 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. |
| 3488 | pub fn ensureDeclAnalyzed(mod: *Module, decl: *Decl) SemaError!void { | 3537 | pub 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(); |
| 3491 | 3540 | ||
| 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, |
| 3494 | 3545 | ||
| ... | @@ -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 { |
| 3507 | 3558 | ||
| 3508 | // The exports this Decl performs will be re-discovered, so we remove them here | 3559 | // 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(); |
| 3532 | 3584 | ||
| 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 would | 3588 | // 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, ok | 3618 | .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(); |
| 3587 | 3640 | ||
| 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 | } |
| 3608 | 3664 | ||
| 3609 | const gpa = mod.gpa; | 3665 | const gpa = mod.gpa; |
| 3610 | const decl = func.owner_decl; | ||
| 3611 | 3666 | ||
| 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(); |
| 3615 | 3670 | ||
| 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 would | 3674 | // 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 { |
| 3635 | 3690 | ||
| 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 | } |
| 3641 | 3696 | ||
| ... | @@ -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 { |
| 3668 | 3723 | ||
| 3669 | // TODO we can potentially relax this if we store some more information along | 3724 | // TODO we can potentially relax this if we store some more information along |
| 3670 | // with decl dependency edges | 3725 | // 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, ok | 3731 | .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(); |
| 3701 | 3758 | ||
| 3702 | if (file.root_decl != null) return; | 3759 | if (file.root_decl != .none) return; |
| 3703 | 3760 | ||
| 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. |
| 3811 | fn semaDecl(mod: *Module, decl: *Decl) !bool { | 3870 | fn 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(); |
| 3814 | 3873 | ||
| 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(); |
| 3846 | 3908 | ||
| 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); |
| 3923 | 3985 | ||
| 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 | } |
| 3935 | 3997 | ||
| 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 { |
| 3949 | 4011 | ||
| 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 { |
| 3957 | 4019 | ||
| 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 global | 4044 | // 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 dependency | 4045 | // 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 | } |
| 3993 | 4055 | ||
| 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 | } |
| 4012 | 4074 | ||
| ... | @@ -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; |
| 4022 | 4084 | ||
| ... | @@ -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); |
| 4067 | 4129 | ||
| 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 }); |
| 4070 | 4132 | ||
| 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 | } |
| 4075 | 4137 | ||
| ... | @@ -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 token | 4139 | 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 | } |
| 4082 | 4144 | ||
| 4083 | return type_changed; | 4145 | return type_changed; |
| 4084 | } | 4146 | } |
| 4085 | 4147 | ||
| 4086 | /// Returns the depender's index of the dependee. | 4148 | /// Returns the depender's index of the dependee. |
| 4087 | pub fn declareDeclDependency(mod: *Module, depender: *Decl, dependee: *Decl) !void { | 4149 | pub 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); | ||
| 4089 | 4154 | ||
| 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 |
| 4096 | 4161 | ||
| 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 | } |
| 4101 | 4166 | ||
| 4102 | dependee.dependants.putAssumeCapacity(depender, {}); | 4167 | dependee.dependants.putAssumeCapacity(depender_index, {}); |
| 4103 | depender.dependencies.putAssumeCapacity(dependee, {}); | 4168 | depender.dependencies.putAssumeCapacity(dependee_index, {}); |
| 4104 | } | 4169 | } |
| 4105 | 4170 | ||
| 4106 | pub const ImportFileResult = struct { | 4171 | pub 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); |
| 4394 | 4459 | ||
| 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); |
| 4433 | 4498 | ||
| 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, and | 4516 | // 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-filter | 4533 | // 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 may | 4554 | // 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 state | 4571 | // 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 state | 4576 | // 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 state | 4581 | // 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. |
| 4518 | pub fn clearDecl( | 4591 | pub 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(); |
| 4525 | 4598 | ||
| 4599 | const decl = mod.declPtr(decl_index); | ||
| 4526 | log.debug("clearing {*} ({s})", .{ decl, decl.name }); | 4600 | log.debug("clearing {*} ({s})", .{ decl, decl.name }); |
| 4527 | 4601 | ||
| 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()); |
| 4530 | 4604 | ||
| 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 | } |
| 4535 | 4609 | ||
| 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(); |
| 4550 | 4625 | ||
| 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(); |
| 4559 | 4635 | ||
| 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); |
| 4571 | 4647 | ||
| 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); |
| 4575 | 4651 | ||
| 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( |
| 4604 | 4680 | ||
| 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 | } |
| 4609 | 4685 | ||
| 4610 | decl.analysis = .unreferenced; | 4686 | decl.analysis = .unreferenced; |
| 4611 | } | 4687 | } |
| 4612 | 4688 | ||
| 4613 | /// This function is exclusively called for anonymous decls. | 4689 | /// This function is exclusively called for anonymous decls. |
| 4614 | pub fn deleteUnusedDecl(mod: *Module, decl: *Decl) void { | 4690 | pub 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 }); | ||
| 4616 | 4693 | ||
| 4617 | // TODO: remove `allocateDeclIndexes` and make the API that the linker backends | 4694 | // TODO: remove `allocateDeclIndexes` and make the API that the linker backends |
| 4618 | // are required to notice the first time `updateDecl` happens and keep track | 4695 | // 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 API | 4703 | .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 | } |
| 4633 | 4710 | ||
| 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)); |
| 4636 | 4713 | ||
| 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 | } |
| 4641 | 4718 | ||
| 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 | } |
| 4647 | 4724 | ||
| 4648 | /// We don't perform a deletion here, because this Decl or another one | 4725 | /// 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. |
| 4650 | fn markDeclForDeletion(mod: *Module, decl: *Decl) !void { | 4727 | fn 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 | } |
| 4654 | 4732 | ||
| 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. |
| 4657 | pub fn abortAnonDecl(mod: *Module, decl: *Decl) void { | 4735 | pub 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 }); |
| 4659 | 4738 | ||
| 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)); |
| 4662 | 4741 | ||
| 4663 | // An aborted decl must not have dependants -- they must have | 4742 | // 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); |
| 4666 | 4745 | ||
| 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 | } |
| 4670 | 4750 | ||
| 4671 | decl.destroy(mod); | 4751 | mod.destroyDecl(decl_index); |
| 4672 | } | 4752 | } |
| 4673 | 4753 | ||
| 4674 | /// Delete all the Export objects that are caused by this Decl. Re-analysis of | 4754 | /// 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). |
| 4676 | fn deleteDeclExports(mod: *Module, decl: *Decl) void { | 4756 | fn 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; |
| 4678 | 4758 | ||
| 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 | } |
| 4715 | 4795 | ||
| 4716 | pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: Allocator) SemaError!Air { | 4796 | pub 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(); |
| 4719 | 4799 | ||
| 4720 | const gpa = mod.gpa; | 4800 | const gpa = mod.gpa; |
| 4801 | const decl_index = func.owner_decl; | ||
| 4802 | const decl = mod.declPtr(decl_index); | ||
| 4721 | 4803 | ||
| 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 | } |
| 4905 | 4988 | ||
| 4906 | fn markOutdatedDecl(mod: *Module, decl: *Decl) !void { | 4989 | fn 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 | } |
| 4926 | 5010 | ||
| 4927 | pub fn allocateNewDecl( | 5011 | pub 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); | ||
| 4943 | 5037 | ||
| 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 | }; |
| 4988 | 5082 | ||
| 4989 | return new_decl; | 5083 | return decl_and_index.decl_index; |
| 4990 | } | 5084 | } |
| 4991 | 5085 | ||
| 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 | } |
| 5012 | 5106 | ||
| 5013 | /// Takes ownership of `name` even if it returns an error. | 5107 | pub fn createAnonymousDecl(mod: *Module, block: *Sema.Block, typed_value: TypedValue) !Decl.Index { |
| 5014 | pub 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 | |||
| 5023 | pub 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 | } |
| 5026 | 5111 | ||
| 5027 | pub fn createAnonymousDeclFromDecl( | 5112 | pub 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 | } |
| 5040 | 5127 | ||
| 5041 | /// Takes ownership of `name` even if it returns an error. | 5128 | /// Takes ownership of `name` even if it returns an error. |
| 5042 | pub fn createAnonymousDeclFromDeclNamed( | 5129 | pub 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); |
| 5051 | 5138 | ||
| 5052 | try namespace.anon_decls.ensureUnusedCapacity(mod.gpa, 1); | 5139 | const new_decl = mod.declPtr(new_decl_index); |
| 5053 | 5140 | ||
| 5054 | const new_decl = try mod.allocateNewDecl(name, namespace, src_decl.src_node, src_scope); | 5141 | new_decl.name = name; |
| 5055 | 5142 | 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; |
| 5064 | 5150 | ||
| 5065 | namespace.anon_decls.putAssumeCapacityNoClobber(new_decl, {}); | 5151 | try namespace.anon_decls.putNoClobber(mod.gpa, new_decl_index, {}); |
| 5066 | 5152 | ||
| 5067 | // The Decl starts off with alive=false and the codegen backend will set alive=true | 5153 | // 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 sent | 5155 | // 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 | |||
| 5079 | pub fn getNextAnonNameIndex(mod: *Module) usize { | ||
| 5080 | return @atomicRmw(usize, &mod.next_anon_name_index, .Add, 1, .Monotonic); | ||
| 5081 | } | 5161 | } |
| 5082 | 5162 | ||
| 5083 | pub fn makeIntType(arena: Allocator, signedness: std.builtin.Signedness, bits: u16) !Type { | 5163 | pub 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 after | 5419 | // 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 be | 5420 | // 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(); |
| 5350 | 5430 | ||
| ... | @@ -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 the | 5436 | // 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 the | 5437 | // `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 }); |
| 5361 | 5442 | ||
| 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 }); |
| 5365 | 5446 | ||
| 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(); |
| 5434 | 5517 | ||
| 5435 | const array_decl = d: { | 5518 | const array_decl_index = d: { |
| 5436 | // Add mod.test_functions to an array decl then make the test_functions | 5519 | // 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(); |
| 5441 | 5524 | ||
| 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); | ||
| 5450 | 5534 | ||
| 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); |
| 5453 | 5537 | ||
| 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); |
| 5470 | 5555 | ||
| 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 | }), // name | 5561 | }), // name |
| 5477 | try Value.Tag.decl_ref.create(arena, test_decl), // func | 5562 | try Value.Tag.decl_ref.create(arena, test_decl_index), // func |
| 5478 | Value.initTag(.null_value), // async_frame_size | 5563 | 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 | } |
| 5482 | 5567 | ||
| 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); |
| 5487 | 5572 | ||
| 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 | }); |
| 5499 | 5584 | ||
| ... | @@ -5506,15 +5591,17 @@ pub fn populateTestFunctions(mod: *Module) !void { | ... | @@ -5506,15 +5591,17 @@ pub fn populateTestFunctions(mod: *Module) !void { |
| 5506 | 5591 | ||
| 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 | } |
| 5511 | 5596 | ||
| 5512 | pub fn linkerUpdateDecl(mod: *Module, decl: *Decl) !void { | 5597 | pub fn linkerUpdateDecl(mod: *Module, decl_index: Decl.Index) !void { |
| 5513 | const comp = mod.comp; | 5598 | const comp = mod.comp; |
| 5514 | 5599 | ||
| 5515 | if (comp.bin_file.options.emit == null) return; | 5600 | if (comp.bin_file.options.emit == null) return; |
| 5516 | 5601 | ||
| 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 | |||
| 5657 | pub 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 | |||
| 5704 | pub 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 | |||
| 5714 | fn 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 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const Order = std.math.Order; | 2 | const Order = std.math.Order; |
| 3 | const Type = @import("type.zig").Type; | 3 | |
| 4 | const Value = @import("value.zig").Value; | ||
| 5 | const RangeSet = @This(); | 4 | const RangeSet = @This(); |
| 5 | const Module = @import("Module.zig"); | ||
| 6 | const SwitchProngSrc = @import("Module.zig").SwitchProngSrc; | 6 | const SwitchProngSrc = @import("Module.zig").SwitchProngSrc; |
| 7 | const Type = @import("type.zig").Type; | ||
| 8 | const Value = @import("value.zig").Value; | ||
| 7 | 9 | ||
| 8 | ranges: std.ArrayList(Range), | 10 | ranges: std.ArrayList(Range), |
| 9 | target: std.Target, | 11 | module: *Module, |
| 10 | 12 | ||
| 11 | pub const Range = struct { | 13 | pub 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 | }; |
| 16 | 18 | ||
| 17 | pub fn init(allocator: std.mem.Allocator, target: std.Target) RangeSet { | 19 | pub 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 | } |
| 23 | 25 | ||
| ... | @@ -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) and | 38 | 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 | } |
| 51 | 51 | ||
| 52 | const LessThanContext = struct { ty: Type, target: std.Target }; | 52 | const LessThanContext = struct { ty: Type, module: *Module }; |
| 53 | 53 | ||
| 54 | /// Assumes a and b do not overlap | 54 | /// Assumes a and b do not overlap |
| 55 | fn lessThan(ctx: LessThanContext, a: Range, b: Range) bool { | 55 | fn 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 | } |
| 58 | 58 | ||
| 59 | pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool { | 59 | pub 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; |
| 62 | 62 | ||
| 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); |
| 69 | 67 | ||
| 70 | if (!self.ranges.items[0].first.eql(first, ty, target) or | 68 | 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(); |
| 80 | 78 | ||
| 79 | const target = self.module.getTarget(); | ||
| 80 | |||
| 81 | // look for gaps | 81 | // 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`. |
| 26 | owner_decl: *Decl, | 26 | owner_decl: *Decl, |
| 27 | owner_decl_index: Decl.Index, | ||
| 27 | /// For an inline or comptime function call, this will be the root parent function | 28 | /// 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`. |
| 29 | owner_func: ?*Module.Fn, | 30 | owner_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 did | 48 | /// access to the source location set by the previous instruction which did |
| 48 | /// contain a mapped source location. | 49 | /// contain a mapped source location. |
| 49 | src: LazySrcLoc = .{ .token_offset = 0 }, | 50 | src: LazySrcLoc = .{ .token_offset = 0 }, |
| 50 | decl_val_table: std.AutoHashMapUnmanaged(*Decl, Air.Inst.Ref) = .{}, | 51 | decl_val_table: std.AutoHashMapUnmanaged(Decl.Index, Air.Inst.Ref) = .{}, |
| 51 | /// When doing a generic function instantiation, this array collects a | 52 | /// When doing a generic function instantiation, this array collects a |
| 52 | /// `Value` object for each parameter that is comptime known and thus elided | 53 | /// `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` and | 54 | /// 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 block | 115 | /// 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 | } |
| 513 | 514 | ||
| 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 calling | 518 | // 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: off | 684 | // 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 | } |
| 1389 | 1390 | ||
| 1390 | pub fn resolveType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !Type { | 1391 | pub 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 | } |
| 1539 | 1540 | ||
| 1540 | fn failWithModRemNegative(sema: *Sema, block: *Block, src: LazySrcLoc, lhs_ty: Type, rhs_ty: Type) CompileError { | 1541 | fn 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 | } |
| 1546 | 1546 | ||
| 1547 | fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, optional_ty: Type) CompileError { | 1547 | fn 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 | } |
| 1551 | 1550 | ||
| 1552 | fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError { | 1551 | fn 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 | } |
| 1558 | 1556 | ||
| 1559 | fn failWithStructInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError { | 1557 | fn 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 | } |
| 1565 | 1562 | ||
| ... | @@ -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 | } |
| 1578 | 1574 | ||
| ... | @@ -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 | } |
| 1591 | 1589 | ||
| 1592 | fn addFieldErrNote( | 1590 | fn 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 | } |
| 1606 | 1606 | ||
| 1607 | fn errMsg( | 1607 | fn 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 | } |
| 1616 | 1618 | ||
| 1617 | pub fn fail( | 1619 | pub 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); |
| 1757 | 1759 | ||
| 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 | } |
| 1829 | 1831 | ||
| 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(); |
| 1926 | 1928 | ||
| 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 | } |
| 1958 | 1961 | ||
| 1959 | fn createTypeName( | 1962 | fn 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 has | 1978 | // 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 be | 1982 | // 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); |
| 1983 | 1998 | ||
| 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("("); |
| 1988 | 2003 | ||
| 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; |
| 1996 | 2011 | ||
| 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)}); |
| 1999 | 2014 | ||
| 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 | }; |
| 2005 | 2020 | ||
| 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); |
| 2074 | 2091 | ||
| 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; |
| 2107 | 2124 | ||
| ... | @@ -2116,8 +2133,13 @@ fn zirEnumDecl( | ... | @@ -2116,8 +2133,13 @@ fn zirEnumDecl( |
| 2116 | // should be the enum itself. | 2133 | // should be the enum itself. |
| 2117 | 2134 | ||
| 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 | } | ||
| 2121 | 2143 | ||
| 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 | } |
| 2174 | 2196 | ||
| ... | @@ -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 | } |
| 2236 | 2258 | ||
| 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 | } |
| 2240 | 2262 | ||
| 2241 | fn zirUnionDecl( | 2263 | fn 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 | }); |
| 2306 | 2329 | ||
| 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); |
| 2308 | 2331 | ||
| 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 | } |
| 2312 | 2335 | ||
| 2313 | fn zirOpaqueDecl( | 2336 | fn 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); |
| 2357 | 2380 | ||
| 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); |
| 2372 | 2395 | ||
| 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 | } |
| 2376 | 2399 | ||
| 2377 | fn zirErrorSetDecl( | 2400 | fn 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); |
| 2405 | 2429 | ||
| 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_string | 2435 | 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 AstGen | 2439 | 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); |
| 2420 | 2444 | ||
| 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 | } |
| 2429 | 2453 | ||
| 2430 | fn zirRetPtr( | 2454 | fn zirRetPtr( |
| ... | @@ -2444,7 +2468,7 @@ fn zirRetPtr( | ... | @@ -2444,7 +2468,7 @@ fn zirRetPtr( |
| 2444 | } | 2468 | } |
| 2445 | 2469 | ||
| 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 | else | 2559 | else |
| 2536 | object_ty; | 2560 | object_ty; |
| 2537 | 2561 | ||
| 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); |
| 2653 | 2676 | ||
| 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); |
| 2781 | 2804 | ||
| 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 |
| 2791 | 2815 | ||
| 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); |
| 2805 | 2829 | ||
| 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; |
| 2875 | 2899 | ||
| 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); |
| 2887 | 2911 | ||
| 2888 | // Even though we reuse the constant instruction, we still remove it from the | 2912 | // 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_const | 2916 | // 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 | } |
| 3219 | 3243 | ||
| 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 | } |
| 3326 | 3351 | ||
| 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; |
| 3519 | 3543 | ||
| 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); |
| 3522 | 3546 | ||
| 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; |
| 3545 | 3569 | ||
| 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); |
| 3548 | 3572 | ||
| 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 | } |
| 3562 | 3586 | ||
| 3563 | fn addDeclaredHereNote(sema: *Sema, parent: *Module.ErrorMsg, decl_ty: Type) !void { | 3587 | fn 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(); | ||
| 3873 | 3896 | ||
| 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", .{}); |
| 3888 | 3911 | ||
| 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); |
| 3998 | 4021 | ||
| 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)}); |
| 4001 | 4025 | ||
| 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); |
| 4006 | 4030 | ||
| 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", .{}); |
| 4009 | 4033 | ||
| 4010 | for (c_import_res.errors) |_| { | 4034 | for (c_import_res.errors) |_| { |
| 4011 | // TODO integrate with LazySrcLoc | 4035 | // 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_path | 4052 | 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); |
| 4034 | 4058 | ||
| 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)}); |
| 4037 | 4061 | ||
| 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)}); |
| 4040 | 4064 | ||
| 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 | } |
| 4046 | 4071 | ||
| ... | @@ -4139,6 +4164,7 @@ fn analyzeBlockBody( | ... | @@ -4139,6 +4164,7 @@ fn analyzeBlockBody( |
| 4139 | defer tracy.end(); | 4164 | defer tracy.end(); |
| 4140 | 4165 | ||
| 4141 | const gpa = sema.gpa; | 4166 | const gpa = sema.gpa; |
| 4167 | const mod = sema.mod; | ||
| 4142 | 4168 | ||
| 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( |
| 4173 | 4199 | ||
| 4174 | const type_src = src; // TODO: better source location | 4200 | 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); |
| 4181 | 4206 | ||
| 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", .{}); |
| 4184 | 4209 | ||
| 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); | ||
| 4186 | 4212 | ||
| 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 | } |
| 4269 | 4295 | ||
| 4270 | fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { | 4296 | fn 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 | } |
| 4287 | 4313 | ||
| 4288 | pub fn analyzeExport( | 4314 | pub 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(); | ||
| 4298 | 4323 | ||
| 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 fields | 4326 | // 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 | } |
| 4307 | 4333 | ||
| ... | @@ -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); |
| 4321 | 4347 | ||
| 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 | }; |
| 4351 | 4370 | ||
| 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); |
| 4360 | 4379 | ||
| 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 orelse | 4400 | 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", .{}); |
| 4383 | 4402 | ||
| 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 | } |
| 4567 | 4587 | ||
| 4568 | fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 4588 | fn 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 | } |
| 4575 | 4595 | ||
| 4576 | fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: []const u8) !*Decl { | 4596 | fn 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; |
| 4598 | 4618 | ||
| 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 | } |
| 4604 | 4625 | ||
| ... | @@ -4610,7 +4631,7 @@ fn lookupInNamespace( | ... | @@ -4610,7 +4631,7 @@ fn lookupInNamespace( |
| 4610 | defer checked_namespaces.deinit(gpa); | 4631 | defer checked_namespaces.deinit(gpa); |
| 4611 | 4632 | ||
| 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); |
| 4615 | 4636 | ||
| 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( |
| 4618 | 4639 | ||
| 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 different | 4643 | // 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 in | 4656 | // 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 | } |
| 4668 | 4692 | ||
| 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 dependency | 4696 | // 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 of | 4697 | // 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 | } |
| 4678 | 4702 | ||
| ... | @@ -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, |
| 4729 | 4753 | ||
| 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 dependency | 4756 | // 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; |
| 4736 | 4761 | ||
| 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 { |
| 4747 | 4772 | ||
| 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; |
| 4788 | 4813 | ||
| 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 | }; |
| 4804 | 4828 | ||
| 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 rather | 4946 | // 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; |
| 4927 | 4952 | ||
| 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; |
| 4938 | 4963 | ||
| 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(); |
| 4941 | 4966 | ||
| 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; |
| 4978 | 5003 | ||
| 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; |
| 4982 | 5007 | ||
| ... | @@ -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 | }; |
| 5151 | 5176 | ||
| 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 | } |
| 5155 | 5186 | ||
| 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 we | 5276 | // 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 a | 5277 | // 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)); |
| 5262 | 5294 | ||
| 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(); | ||
| 5265 | 5296 | ||
| 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 location | 5321 | 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); |
| 5344 | 5375 | ||
| 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 instantiations | 5382 | // 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; |
| 5364 | 5397 | ||
| 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)); |
| 5367 | 5400 | ||
| 5368 | // The generic function Decl is guaranteed to be the first dependency | 5401 | // 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 dependencies | 5405 | // 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 | } |
| 5379 | 5413 | ||
| ... | @@ -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` field | 5599 | // 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 ZIR | 5600 | // 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 }); |
| 5569 | 5604 | ||
| 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); |
| 5578 | 5613 | ||
| 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); | ||
| 5705 | 5739 | ||
| 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); | ||
| 5725 | 5758 | ||
| 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(); | ||
| 5752 | 5784 | ||
| 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 | } |
| 5761 | 5793 | ||
| ... | @@ -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)}); |
| 5870 | 5901 | ||
| 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(); | ||
| 5916 | 5946 | ||
| 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 | } |
| 5954 | 5984 | ||
| 5955 | fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 5985 | fn 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); |
| 5964 | 5993 | ||
| 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 | } |
| 5968 | 5997 | ||
| 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); |
| 6030 | 6059 | ||
| 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 | } |
| 6036 | 6064 | ||
| 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 | } |
| 6162 | 6188 | ||
| ... | @@ -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); |
| 6207 | 6233 | ||
| 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 | } |
| 6214 | 6239 | ||
| 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 | } |
| 6281 | 6305 | ||
| ... | @@ -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); |
| 6303 | 6327 | ||
| 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 | } |
| 6310 | 6333 | ||
| ... | @@ -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); |
| 6607 | 6629 | ||
| 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 | }; |
| 6612 | 6634 | ||
| ... | @@ -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(); | ||
| 7022 | 7042 | ||
| 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)}), |
| 7042 | 7062 | ||
| 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 | }; |
| 7094 | 7114 | ||
| ... | @@ -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 | } |
| 7105 | 7125 | ||
| ... | @@ -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(); | ||
| 7245 | 7264 | ||
| 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 succeed | 7296 | // 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; |
| 7279 | 7298 | ||
| 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]; |
| 7282 | 7301 | ||
| 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 succeed | 7304 | // 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; |
| 7287 | 7306 | ||
| 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 location | 7310 | 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); |
| 7306 | 7325 | ||
| 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 | else | 7407 | 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(); | ||
| 7392 | 7410 | ||
| 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 | } |
| 7442 | 7460 | ||
| ... | @@ -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 |
| 7705 | 7723 | ||
| 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(); |
| 7743 | 7761 | ||
| 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 | } |
| 7920 | 7938 | ||
| 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(); |
| 7926 | 7944 | ||
| ... | @@ -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 | } |
| 7991 | 8009 | ||
| ... | @@ -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) and | 8093 | 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 }; |
| 8560 | 8579 | ||
| 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(); | ||
| 8591 | 8608 | ||
| 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); |
| 8634 | 8651 | ||
| 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 | } |
| 8668 | 8687 | ||
| ... | @@ -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. |
| 8927 | 8946 | ||
| 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 | } |
| 8933 | 8952 | ||
| ... | @@ -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 }; |
| 9049 | 9068 | ||
| 9050 | const target = sema.mod.getTarget(); | ||
| 9051 | const lhs_info = (try sema.getArrayCatInfo(block, lhs_src, lhs)) orelse | 9069 | 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)) orelse | 9071 | 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 | } |
| 9060 | 9078 | ||
| ... | @@ -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 |
| 9123 | 9141 | ||
| 9124 | fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, inst: Air.Inst.Ref) !?Type.ArrayInfo { | 9142 | fn 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(); | ||
| 9233 | 9249 | ||
| 9234 | const mulinfo = (try sema.getArrayCatInfo(block, lhs_src, lhs)) orelse | 9250 | 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)}); |
| 9236 | 9252 | ||
| 9237 | const final_len_u64 = std.math.mul(u64, mulinfo.len, factor) catch | 9253 | 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, such | 9280 | // 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(); |
| 9312 | 9328 | ||
| 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 | } |
| 9317 | 9332 | ||
| 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); |
| 9365 | 9380 | ||
| 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(); | ||
| 9368 | 9384 | ||
| 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 | } |
| 9374 | 9390 | ||
| 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 | } |
| 9598 | 9614 | ||
| 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(); | ||
| 10609 | 10625 | ||
| 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( |
| 10630 | 10646 | ||
| 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 | } |
| 10635 | 10651 | ||
| 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( |
| 10777 | 10791 | ||
| 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 | } |
| 10783 | 10797 | ||
| 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)}), |
| 10853 | 10867 | ||
| 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 | } |
| 10899 | 10913 | ||
| 10900 | fn zirClosureCapture( | 10914 | fn 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 functions | 10942 | // 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); | ||
| 10976 | 10991 | ||
| 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 | } |
| 11119 | 11134 | ||
| 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 |
| 11307 | 11324 | ||
| 11308 | // Get the Error type | 11325 | // 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(); |
| 11417 | 11435 | ||
| 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(); |
| 11515 | 11534 | ||
| 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(); |
| 11622 | 11642 | ||
| 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(); |
| 11812 | 11833 | ||
| 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 | } |
| 11958 | 11980 | ||
| ... | @@ -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 |
| 12426 | 12448 | ||
| 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, in | 12487 | // 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; |
| 12755 | 12776 | ||
| 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( |
| 12782 | 12803 | ||
| 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( |
| 12851 | 12872 | ||
| 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; |
| 12864 | 12885 | ||
| 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( |
| 12949 | 12970 | ||
| 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); |
| 12957 | 12978 | ||
| 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( |
| 13017 | 13038 | ||
| 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 | } |
| 13224 | 13244 | ||
| 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; |
| 13271 | 13291 | ||
| 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 | } |
| 13318 | 13340 | ||
| 13319 | fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 13341 | fn 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 | } |
| 13415 | 13438 | ||
| 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; |
| 13448 | 13471 | ||
| 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() orelse | 13506 | 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; |
| 13489 | 13513 | ||
| 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 here | 13518 | // 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); |
| 13498 | 13522 | ||
| 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 | } |
| 13502 | 13526 | ||
| ... | @@ -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]; |
| 13519 | 13543 | ||
| 13520 | // Decls | 13544 | // 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 | } |
| 13524 | 13548 | ||
| ... | @@ -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 | } |
| 13549 | 13573 | ||
| 13550 | // Decls | 13574 | // 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 | } |
| 13554 | 13578 | ||
| 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); |
| 13582 | 13605 | ||
| 13583 | // Enum tag type | 13606 | // 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); |
| 13586 | 13609 | ||
| 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 | }; |
| 13600 | 13623 | ||
| 13601 | // Fields | 13624 | // 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 | }); |
| 13609 | 13632 | ||
| 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 here | 13637 | // TODO use reflection instead of magic numbers here |
| 13615 | // name: []const u8 | 13638 | // 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 | ); |
| 13625 | 13648 | ||
| 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 | } |
| 13639 | 13662 | ||
| 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]; |
| 13647 | 13670 | ||
| 13648 | // Decls | 13671 | // 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 | } |
| 13652 | 13675 | ||
| 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); |
| 13673 | 13695 | ||
| 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 | }; |
| 13683 | 13705 | ||
| 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 here | 13710 | // 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]; |
| 13698 | 13720 | ||
| 13699 | // Decls | 13721 | // 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 | } |
| 13703 | 13725 | ||
| ... | @@ -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 | }; |
| 13738 | 13760 | ||
| 13739 | // Tag type | 13761 | // 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 |
| 13749 | 13771 | ||
| 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 here | 13776 | // TODO use reflection instead of magic numbers here |
| 13755 | // name: []const u8 | 13777 | // 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 | ); |
| 13767 | 13789 | ||
| 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 | } |
| 13781 | 13803 | ||
| 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)); |
| 13801 | 13821 | ||
| 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( |
| 13808 | 13828 | ||
| 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 here | 13833 | // TODO use reflection instead of magic numbers here |
| 13814 | // name: []const u8 | 13834 | // 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 | ); |
| 13826 | 13846 | ||
| 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( |
| 13850 | 13870 | ||
| 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.val | 13873 | sema.mod.declPtr(opt_decl).val |
| 13854 | else | 13874 | 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 | }; |
| 13907 | 13928 | ||
| 13908 | const target = sema.mod.getTarget(); | 13929 | const target = mod.getTarget(); |
| 13909 | 13930 | ||
| 13910 | // Fields | 13931 | // 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 here | 13938 | // TODO use reflection instead of magic numbers here |
| 13918 | // name: []const u8 | 13939 | // 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 | ); |
| 13934 | 13955 | ||
| 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( |
| 13940 | 13961 | ||
| 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.val | 13964 | mod.declPtr(opt_decl).val |
| 13944 | else | 13965 | 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 | } |
| 13958 | 13979 | ||
| 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 | } |
| 13962 | 13983 | ||
| 13963 | fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 13984 | fn 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(); |
| 13970 | 13991 | ||
| 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); | ||
| 13973 | 13993 | ||
| 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)}); |
| 14070 | 14090 | ||
| 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); |
| 14116 | 14135 | ||
| ... | @@ -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 | }; |
| 14188 | 14207 | ||
| ... | @@ -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 |
| 14235 | 14254 | ||
| 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 correct | 14321 | // TODO insert safety check that the alignment is correct |
| 14303 | 14322 | ||
| 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 | } |
| 14392 | 14410 | ||
| ... | @@ -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 | } |
| 14512 | 14530 | ||
| ... | @@ -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 | }; |
| 14522 | 14540 | ||
| ... | @@ -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 | } |
| 14543 | 14561 | ||
| 14544 | fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void { | 14562 | fn 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 | } |
| 14551 | 14568 | ||
| 14552 | /// Returns `true` if the type was a comptime_int. | 14569 | /// Returns `true` if the type was a comptime_int. |
| 14553 | fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool { | 14570 | fn 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 | } |
| 14561 | 14577 | ||
| ... | @@ -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); |
| 14580 | 14595 | ||
| ... | @@ -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 | } |
| 14592 | 14607 | ||
| 14593 | fn checkPtrType( | 14608 | fn 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); |
| 14611 | 14625 | ||
| ... | @@ -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 | } |
| 14623 | 14637 | ||
| 14624 | fn checkVectorElemType( | 14638 | fn 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 | } |
| 14637 | 14650 | ||
| 14638 | fn checkFloatType( | 14651 | fn 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 | } |
| 14650 | 14662 | ||
| ... | @@ -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 | } |
| 14667 | 14678 | ||
| ... | @@ -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 | } |
| 14806 | 14815 | ||
| 14807 | fn checkErrorSetType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void { | 14816 | fn 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 | } |
| 14814 | 14822 | ||
| ... | @@ -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, // TODO | 14947 | .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(); |
| 15104 | 15109 | ||
| 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 | } |
| 15108 | 15113 | ||
| 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); |
| 15136 | 15141 | ||
| 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(); | ||
| 15178 | 15182 | ||
| 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 | }); |
| 15212 | 15216 | ||
| 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( |
| 15272 | 15275 | ||
| 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 | }); |
| 15277 | 15280 | ||
| 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( |
| 15358 | fn zirSelect(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 15361 | fn 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(); | ||
| 15362 | 15364 | ||
| 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. |
| 15372 | 15374 | ||
| 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); |
| 15378 | 15380 | ||
| ... | @@ -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 | } |
| 15410 | 15412 | ||
| ... | @@ -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. |
| 15630 | 15632 | ||
| 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 | } |
| 15635 | 15637 | ||
| 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 | }; |
| 15706 | 15708 | ||
| 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 | } |
| 15712 | 15713 | ||
| 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(); | ||
| 15748 | 15748 | ||
| 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); |
| 15753 | 15753 | ||
| ... | @@ -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); |
| 15757 | 15757 | ||
| 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 | } |
| 15775 | 15775 | ||
| 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); |
| 15778 | 15778 | ||
| 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); |
| 15781 | 15781 | ||
| 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(); | ||
| 15882 | 15881 | ||
| 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 | } |
| 15887 | 15886 | ||
| 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 | }); |
| 16058 | 16056 | ||
| 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 field | 16061 | .is_mutable = true, // TODO get rid of this unused field |
| ... | @@ -16294,7 +16292,7 @@ fn zirBuiltinExtern( | ... | @@ -16294,7 +16292,7 @@ fn zirBuiltinExtern( |
| 16294 | 16292 | ||
| 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; |
| 16298 | 16296 | ||
| 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 | } |
| 16320 | 16318 | ||
| 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( |
| 16344 | 16342 | ||
| 16345 | // TODO check duplicate extern | 16343 | // TODO check duplicate extern |
| 16346 | 16344 | ||
| 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); | ||
| 16349 | 16349 | ||
| 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); |
| 16356 | 16356 | ||
| 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 field | 16361 | .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; |
| 16382 | 16382 | ||
| 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; |
| 16386 | 16386 | ||
| 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; |
| 16414 | 16414 | ||
| 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); |
| 16419 | 16420 | ||
| 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); | ||
| 16421 | 16423 | ||
| 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( |
| 16503 | 16504 | ||
| 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 | }, |
| 16509 | 16510 | ||
| ... | @@ -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 dynamic | 16674 | .@"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 | else | 16749 | else |
| 16749 | object_ty; | 16750 | object_ty; |
| 16750 | 16751 | ||
| 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; |
| 16828 | 16827 | ||
| ... | @@ -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 | } |
| 16903 | 16902 | ||
| 16904 | fn fieldPtr( | 16903 | fn 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 edited | 16911 | // 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. |
| 16914 | 16913 | ||
| 16915 | const target = sema.mod.getTarget(); | ||
| 16916 | const object_ptr_src = src; // TODO better source location | 16914 | 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 | }; |
| 16922 | 16920 | ||
| 16923 | // Zig allows dereferencing a single pointer during field lookup. Note that | 16921 | // 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); |
| 16973 | 16971 | ||
| 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( |
| 16985 | 16983 | ||
| 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 alignment | 16987 | 0, // default alignment |
| 16990 | )); | 16988 | )); |
| 16991 | } | 16989 | } |
| 16992 | try sema.requireRuntimeBlock(block, src); | 16990 | try sema.requireRuntimeBlock(block, src); |
| 16993 | 16991 | ||
| 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; |
| 17033 | 17031 | ||
| ... | @@ -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 | } |
| 17109 | 17107 | ||
| 17110 | fn fieldCallBind( | 17108 | fn 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 edited | 17116 | // 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. |
| 17120 | 17118 | ||
| 17121 | const target = sema.mod.getTarget(); | ||
| 17122 | const raw_ptr_src = src; // TODO better source location | 17119 | 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 | else | 17123 | 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)}); |
| 17128 | 17125 | ||
| 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 and | 17181 | first_param_type.zigTypeTag() == .Pointer and |
| 17185 | (first_param_type.ptrSize() == .One or | 17182 | (first_param_type.ptrSize() == .One or |
| 17186 | first_param_type.ptrSize() == .C) and | 17183 | 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: on | 17186 | // zig fmt: on |
| 17190 | // TODO: bound fn calls on rvalues should probably | 17187 | // 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 | } |
| 17213 | 17210 | ||
| 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 | } |
| 17216 | 17213 | ||
| 17217 | fn finishFieldCallBind( | 17214 | fn 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 | } |
| 17379 | 17376 | ||
| 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); |
| 17381 | 17378 | ||
| 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 active | 17559 | // // 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 | } |
| 17663 | 17657 | ||
| 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 | }; |
| 17682 | 17676 | ||
| ... | @@ -17713,7 +17707,7 @@ fn elemVal( | ... | @@ -17713,7 +17707,7 @@ fn elemVal( |
| 17713 | const target = sema.mod.getTarget(); | 17707 | const target = sema.mod.getTarget(); |
| 17714 | 17708 | ||
| 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 | } |
| 17718 | 17712 | ||
| 17719 | // TODO in case of a vector of pointers, we need to detect whether the element | 17713 | // 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 | } |
| 17786 | 17780 | ||
| 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); |
| 17918 | 17911 | ||
| 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( |
| 17977 | 17970 | ||
| 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 | else | 17996 | 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); |
| 18024 | 18017 | ||
| 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 bounds | 18019 | // 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; |
| 18084 | 18077 | ||
| 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 [*]T | 18178 | // *[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 or | 18249 | 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; |
| 18259 | 18252 | ||
| 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 | } |
| 18335 | 18328 | ||
| 18336 | if (dest_info.sentinel == null or inst_info.sentinel == null or | 18329 | 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; |
| 18339 | 18332 | ||
| 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; |
| 18348 | 18341 | ||
| 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 number | 18360 | // 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 error | 18414 | // 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 type | 18461 | // 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 | } |
| 18559 | 18557 | ||
| 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 | } |
| 18562 | 18560 | ||
| 18563 | const InMemoryCoercionResult = enum { | 18561 | const 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; |
| 18591 | 18589 | ||
| 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 or | 18649 | const ok_sent = dest_info.sentinel == null or |
| 18652 | (src_info.sentinel != null and | 18650 | (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( |
| 18893 | 18891 | ||
| 18894 | const ok_sent = dest_info.sentinel == null or src_info.size == .C or | 18892 | const ok_sent = dest_info.sentinel == null or src_info.size == .C or |
| 18895 | (src_info.sentinel != null and | 18893 | (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 and | 18934 | 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 and | 19087 | // 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( |
| 19114 | 19111 | ||
| 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); |
| 19116 | 19113 | ||
| 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); |
| 19119 | 19116 | ||
| 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, |
| 19128 | 19125 | ||
| 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 | } |
| 19133 | 19131 | ||
| 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 we | 19178 | // 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 representation | 19179 | // 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); |
| 19183 | 19183 | ||
| 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 detection | 19200 | // 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 stored | 19201 | // 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); |
| 19205 | 19205 | ||
| 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 an | 19229 | // 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 it | 19230 | // 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); |
| 19234 | 19234 | ||
| 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 we | 19281 | // 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 representation | 19282 | // 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); |
| 19286 | 19286 | ||
| 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); |
| 19327 | 19327 | ||
| 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 we | 19347 | // 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 the | 19348 | // 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); |
| 19352 | 19352 | ||
| 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 we | 19380 | // An optional has been initialized to undefined at comptime and now we |
| 19381 | // are for the first time setting the payload. We must change the | 19381 | // 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); |
| 19385 | 19385 | ||
| 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; |
| 19462 | 19463 | ||
| ... | @@ -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 dereference | 19478 | // 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 that | 19479 | // 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 | } | ||
| 19481 | 19484 | ||
| 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 slice | 19514 | // 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( |
| 19522 | 19525 | ||
| 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( |
| 19637 | 19640 | ||
| 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; |
| 19666 | 19669 | ||
| 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(); | ||
| 19722 | 19724 | ||
| 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); |
| 19759 | 19761 | ||
| ... | @@ -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); |
| 19801 | 19803 | ||
| ... | @@ -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(); | ||
| 19963 | 19964 | ||
| 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 | } |
| 20158 | 20158 | ||
| 20159 | fn ensureDeclAnalyzed(sema: *Sema, decl: *Decl) CompileError!void { | 20159 | fn 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 alignment | 20187 | 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 | } |
| 20192 | 20192 | ||
| ... | @@ -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 | } |
| 20199 | 20199 | ||
| 20200 | fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref { | 20200 | fn 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); |
| 20203 | 20203 | ||
| 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 | } |
| 20225 | 20225 | ||
| ... | @@ -20243,13 +20243,12 @@ fn analyzeRef( | ... | @@ -20243,13 +20243,12 @@ fn analyzeRef( |
| 20243 | 20243 | ||
| 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; | ||
| 20422 | 20420 | ||
| 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 | } |
| 20470 | 20468 | ||
| 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 | else | 20496 | 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 sentinel | 20511 | // end_is_len is only true if we are NOT using the sentinel |
| 20514 | // length. For sentinel-length, we don't want the type to | 20512 | // 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 | else | 20536 | 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 | } |
| 20559 | 20557 | ||
| 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 <= end | 20588 | // 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); |
| 20615 | 20613 | ||
| 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 | } |
| 20643 | 20641 | ||
| 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 the | 20666 | // we don't need to add one for sentinels because the |
| 20669 | // underlying value data includes the sentinel | 20667 | // 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 | } |
| 20672 | 20670 | ||
| 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); |
| 20921 | 20919 | ||
| 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(); | ||
| 20924 | 20921 | ||
| 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(); |
| 21082 | 21079 | ||
| 21083 | if (candidate_ty.eql(chosen_ty, target)) | 21080 | if (candidate_ty.eql(chosen_ty, sema.mod)) |
| 21084 | continue; | 21081 | continue; |
| 21085 | 21082 | ||
| 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 | ); |
| 21507 | 21504 | ||
| 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); |
| 21514 | 21511 | ||
| 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)}); |
| 21517 | 21514 | ||
| 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)}); |
| 21520 | 21517 | ||
| 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 | }; |
| 21540 | 21537 | ||
| 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 | else | 21541 | 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 | } |
| 21549 | 21546 | ||
| 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 | else | 21557 | 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 | else | 21568 | 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 | } |
| 21588 | 21585 | ||
| 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 | }; |
| 21597 | 21594 | ||
| 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 | } |
| 21776 | 21771 | ||
| 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 to | 21773 | // 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 set | 21934 | // `*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 failure | 21935 | // 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 that | 21939 | // 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(); |
| 21987 | 21977 | ||
| 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; |
| 22028 | 22018 | ||
| 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(); |
| 22172 | 22164 | ||
| 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; |
| 22219 | 22211 | ||
| 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(); |
| 22223 | 22217 | ||
| 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 name | 22472 | // 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); |
| 22484 | 22480 | ||
| 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 name | 22513 | // 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); |
| 22524 | 22521 | ||
| 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); |
| 22986 | 22983 | ||
| 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(); |
| 22996 | 22992 | ||
| 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 or | 22995 | // 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 expand | 22996 | // 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; |
| 23006 | 23003 | ||
| 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 | } |
| 23013 | 23010 | ||
| ... | @@ -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 must | 23096 | // 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)}); |
| 23103 | 23100 | ||
| 23104 | const load_sz = try sema.typeAbiSize(block, src, load_ty); | 23101 | const load_sz = try sema.typeAbiSize(block, src, load_ty); |
| 23105 | 23102 | ||
| ... | @@ -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 problem | 23112 | // 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 just | 23116 | // 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 | } |
| 23124 | 23121 | ||
| ... | @@ -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 | } |
| 23492 | 23488 |
src/TypedValue.zig+29-23| ... | @@ -1,6 +1,7 @@ | ... | @@ -1,6 +1,7 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const Type = @import("type.zig").Type; | 2 | const Type = @import("type.zig").Type; |
| 3 | const Value = @import("value.zig").Value; | 3 | const Value = @import("value.zig").Value; |
| 4 | const Module = @import("Module.zig"); | ||
| 4 | const Allocator = std.mem.Allocator; | 5 | const Allocator = std.mem.Allocator; |
| 5 | const TypedValue = @This(); | 6 | const TypedValue = @This(); |
| 6 | const Target = std.Target; | 7 | const 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 | } |
| 33 | 34 | ||
| 34 | pub fn eql(a: TypedValue, b: TypedValue, target: std.Target) bool { | 35 | pub 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 | } |
| 38 | 39 | ||
| 39 | pub fn hash(tv: TypedValue, hasher: *std.hash.Wyhash, target: std.Target) void { | 40 | pub 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 | } |
| 42 | 43 | ||
| 43 | pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value { | 44 | pub 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; |
| 48 | 49 | ||
| 49 | const FormatContext = struct { | 50 | const FormatContext = struct { |
| 50 | tv: TypedValue, | 51 | tv: TypedValue, |
| 51 | target: Target, | 52 | mod: *Module, |
| 52 | }; | 53 | }; |
| 53 | 54 | ||
| 54 | pub fn format( | 55 | pub 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 | } |
| 64 | 65 | ||
| 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); |
| 194 | 196 | ||
| 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); |
| 264 | 270 | ||
| 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 | } |
| 239 | 239 | ||
| 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; | ||
| 242 | 244 | ||
| 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 | } |
| 821 | 823 | ||
| 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.ptrAlign | 828 | // 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 { |
| 830 | 832 | ||
| 831 | fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue { | 833 | fn 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 is | 1440 | // 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 multiplication | 1491 | // 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 immediates | 1542 | // 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); |
| 2426 | 2428 | ||
| 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 stack | 2431 | // 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. |
| 2537 | 2539 | ||
| 2538 | // Due to incremental compilation, how function calls are generated depends | 2540 | // 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_bytes | 2554 | coff_file.offset_table_virtual_address + fn_owner_decl.link.coff.offset_table_index * ptr_bytes |
| 2551 | else | 2555 | else |
| 2552 | unreachable; | 2556 | unreachable; |
| 2553 | 2557 | ||
| ... | @@ -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 x30 | 2576 | // 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; |
| 2607 | 2612 | ||
| 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 | } |
| 3862 | 3869 | ||
| 3863 | fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCValue { | 3870 | fn 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); |
| 3866 | 3873 | ||
| ... | @@ -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 | } |
| 3874 | 3881 | ||
| 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.*; |
| 3928 | 3938 |
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 | } |
| 273 | 273 | ||
| 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; | ||
| 276 | 278 | ||
| 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 | } |
| 840 | 842 | ||
| 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.ptrAlign | 847 | // 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 { |
| 849 | 851 | ||
| 850 | fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue { | 852 | fn 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 is | 2703 | // 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 multiplication | 2752 | // 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.ref4 | 3109 | 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_bytes | 3335 | coff_file.offset_table_virtual_address + fn_owner_decl.link.coff.offset_table_index * ptr_bytes |
| 3326 | else | 3336 | else |
| 3327 | unreachable; | 3337 | unreachable; |
| 3328 | 3338 | ||
| ... | @@ -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 | } |
| 4926 | 4936 | ||
| 4927 | fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCValue { | 4937 | fn 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); |
| 4930 | 4940 | ||
| 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.*; |
| 4982 | 4995 |
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 | } |
| 231 | 231 | ||
| 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; | ||
| 234 | 236 | ||
| 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.ref4 | 742 | 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. |
| 769 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { | 772 | fn 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.ptrAlign | 778 | // 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 { |
| 779 | 782 | ||
| 780 | fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue { | 783 | fn 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 operands | 1047 | // 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. |
| 1679 | 1683 | ||
| 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_bytes | 1692 | coff_file.offset_table_virtual_address + fn_owner_decl.link.coff.offset_table_index * ptr_bytes |
| 1687 | else | 1693 | else |
| 1688 | unreachable; | 1694 | unreachable; |
| 1689 | 1695 | ||
| ... | @@ -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", .{}); |
| 1774 | 1781 | ||
| ... | @@ -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 | } |
| 2503 | 2510 | ||
| 2504 | fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCValue { | 2511 | fn 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 mean | 2558 | // 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 | } |
| 245 | 245 | ||
| 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; | ||
| 248 | 250 | ||
| 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; |
| 876 | 879 | ||
| 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 | } |
| 1028 | 1031 | ||
| 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.ptrAlign | 1036 | // 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 { |
| 1037 | 1040 | ||
| 1038 | fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue { | 1041 | fn 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.*; |
| 1378 | 1381 | ||
| ... | @@ -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 | } |
| 1424 | 1427 | ||
| 1425 | fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCValue { | 1428 | fn 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); |
| 1428 | 1431 | ||
| ... | @@ -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 | } |
| 1436 | 1439 | ||
| 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 code | 538 | /// Reference to the function declaration the code |
| 539 | /// section belongs to | 539 | /// section belongs to |
| 540 | decl: *Decl, | 540 | decl: *Decl, |
| 541 | decl_index: Decl.Index, | ||
| 542 | /// Current block depth. Used to calculate the relative difference between a break | ||
| 543 | /// and block | ||
| 544 | block_depth: u32 = 0, | ||
| 541 | air: Air, | 545 | air: Air, |
| 542 | liveness: Liveness, | 546 | liveness: Liveness, |
| 543 | gpa: mem.Allocator, | 547 | gpa: mem.Allocator, |
| ... | @@ -559,9 +563,6 @@ local_index: u32 = 0, | ... | @@ -559,9 +563,6 @@ local_index: u32 = 0, |
| 559 | arg_index: u32 = 0, | 563 | arg_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` |
| 561 | err_msg: *Module.ErrorMsg, | 565 | err_msg: *Module.ErrorMsg, |
| 562 | /// Current block depth. Used to calculate the relative difference between a break | ||
| 563 | /// and block | ||
| 564 | block_depth: u32 = 0, | ||
| 565 | /// List of all locals' types generated throughout this declaration | 566 | /// 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. |
| 567 | locals: std.ArrayListUnmanaged(u8), | 568 | locals: 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 fits | 645 | // 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); |
| 650 | 651 | ||
| ... | @@ -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 | } |
| 1023 | 1025 | ||
| 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 { |
| 1056 | 1059 | ||
| 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); |
| 1544 | 1548 | ||
| 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.?; | ||
| 1547 | 1552 | ||
| 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 | } |
| 1582 | 1587 | ||
| 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 pointer | 1591 | // 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 |
| 1837 | fn lowerParentPtr(self: *Self, ptr_val: Value, ptr_child_ty: Type) InnerError!WValue { | 1842 | fn 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 | } |
| 1920 | 1925 | ||
| 1921 | fn lowerParentPtrDecl(self: *Self, ptr_val: Value, decl: *Module.Decl) InnerError!WValue { | 1926 | fn 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 | } |
| 1930 | 1937 | ||
| 1931 | fn lowerDeclRefValue(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!WValue { | 1938 | fn 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 | } |
| 1937 | 1948 | ||
| 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 |
| 1946 | fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue { | 1958 | fn 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 | } |
| 1956 | 1968 | ||
| 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 | }; |
| 2392 | 2407 | ||
| 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 | } |
| 2783 | 2798 | ||
| 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 | }; |
| 2787 | 2803 | ||
| 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 | }; |
| 2816 | 2833 | ||
| 2817 | // Create optional type, set the non-null bit, and store the operand inside the optional type | 2834 | // 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 | } |
| 311 | 311 | ||
| 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; | ||
| 314 | 316 | ||
| 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( |
| 396 | 398 | ||
| 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 fails | 407 | 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 | } |
| 408 | 410 | ||
| 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 | } |
| 917 | 919 | ||
| 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.ptrAlign | 924 | // 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 { |
| 926 | 928 | ||
| 927 | fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue { | 929 | fn 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. |
| 3583 | 3587 | ||
| 3584 | // Due to incremental compilation, how function calls are generated depends | 3588 | // 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 | else | 3603 | 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 *%rax | 3638 | // 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.ref4 | 4021 | 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 | } |
| 6126 | 6135 | ||
| 6127 | fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCValue { | 6136 | fn 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 | } |
| 6139 | 6148 | ||
| 6140 | decl.markAlive(); | 6149 | const module = self.bin_file.options.module.?; |
| 6150 | const decl = module.declPtr(decl_index); | ||
| 6151 | module.markDeclAlive(decl); | ||
| 6141 | 6152 | ||
| 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 | } |
| 6194 | 6205 | ||
| 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( |
| 347 | 347 | ||
| 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( |
| 400 | 402 | ||
| 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 | } |
| 590 | 592 | ||
| 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 ptr | 786 | // 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 length | 800 | // 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 | } |
| 814 | 818 | ||
| 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 | } |
| 821 | 826 | ||
| 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 parameters | 32 | /// Index into the parameters |
| 33 | arg: usize, | 33 | arg: usize, |
| 34 | /// By-value | 34 | /// 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( |
| 58 | 58 | ||
| 59 | const FormatTypeAsCIdentContext = struct { | 59 | const FormatTypeAsCIdentContext = struct { |
| 60 | ty: Type, | 60 | ty: Type, |
| 61 | target: std.Target, | 61 | mod: *Module, |
| 62 | }; | 62 | }; |
| 63 | 63 | ||
| 64 | /// TODO make this not cut off at 128 bytes | 64 | /// 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 | } |
| 77 | 77 | ||
| 78 | pub fn typeToCIdentifier(ty: Type, target: std.Target) std.fmt.Formatter(formatTypeAsCIdentifier) { | 78 | pub 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 | } |
| 84 | 84 | ||
| ... | @@ -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 | } |
| 394 | 393 | ||
| 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 call | 396 | // 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 function | 397 | // 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 | } |
| 407 | 407 | ||
| 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 | } |
| 415 | 415 | ||
| 416 | try dg.renderDeclName(writer, decl); | 416 | try dg.renderDeclName(writer, decl_index); |
| 417 | } | 417 | } |
| 418 | 418 | ||
| 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 | } |
| 839 | 839 | ||
| 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(); |
| 895 | 895 | ||
| ... | @@ -927,8 +927,7 @@ pub const DeclGen = struct { | ... | @@ -927,8 +927,7 @@ pub const DeclGen = struct { |
| 927 | try bw.writeAll(" (*"); | 927 | try bw.writeAll(" (*"); |
| 928 | 928 | ||
| 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; |
| 933 | 932 | ||
| 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 { |
| 982 | 981 | ||
| 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 { |
| 1009 | 1007 | ||
| 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); |
| 1014 | 1012 | ||
| 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("} "); |
| 1073 | 1071 | ||
| 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)}); | ||
| 1077 | 1074 | ||
| 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 { |
| 1090 | 1087 | ||
| 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); |
| 1095 | 1092 | ||
| 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 | } |
| 1171 | 1167 | ||
| ... | @@ -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); |
| 1196 | 1192 | ||
| 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; |
| 1201 | 1196 | ||
| 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)}); | ||
| 1229 | 1223 | ||
| 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 | } |
| 1537 | 1531 | ||
| 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); | ||
| 1540 | 1535 | ||
| 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 | } |
| 1618 | 1613 | ||
| 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 | }; | ||
| 1620 | 1619 | ||
| 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 const | 1640 | // TODO ask the Decl if it is const |
| 1642 | // https://github.com/ziglang/zig/issues/7582 | 1641 | // https://github.com/ziglang/zig/issues/7582 |
| 1643 | 1642 | ||
| 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"); |
| 1646 | 1645 | ||
| 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); |
| 2236 | 2235 | ||
| 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 same | 2238 | // 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)); |
| 2244 | 2242 | ||
| 2245 | // If the source is a constant, writeCValue will emit a brace initialization | 2243 | // 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 | } |
| 2786 | 2785 |
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 { |
| 161 | 161 | ||
| 162 | pub const Object = struct { | 162 | pub 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 of | 186 | /// 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 compilation | 188 | /// 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 { |
| 340 | 341 | ||
| 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); | ||
| 572 | 575 | ||
| 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 | }; |
| 581 | 585 | ||
| 582 | const llvm_func = try dg.resolveLlvmFunction(decl); | 586 | const llvm_func = try dg.resolveLlvmFunction(decl_index); |
| 583 | 587 | ||
| 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 { |
| 632 | 636 | ||
| 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 and | 638 | 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.NoReturn | 641 | llvm.DIFlags.NoReturn |
| 638 | else | 642 | 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 | }; |
| 693 | 697 | ||
| 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 | } |
| 697 | 701 | ||
| 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 | } |
| 719 | 725 | ||
| 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 call | 732 | // 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 | } |
| 816 | 823 | ||
| 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 | } |
| 821 | 828 | ||
| ... | @@ -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 calls | 855 | // 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-lived | 871 | // 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); | ||
| 906 | 914 | ||
| 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 | } |
| 914 | 922 | ||
| ... | @@ -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); |
| 940 | 948 | ||
| 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 | } |
| 1015 | 1023 | ||
| ... | @@ -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; |
| 1020 | 1028 | ||
| 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 | } |
| 1095 | 1103 | ||
| 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 | } |
| 1168 | 1177 | ||
| ... | @@ -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); |
| 1349 | 1358 | ||
| 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 | } |
| 1437 | 1446 | ||
| ... | @@ -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 the | 1455 | // 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 | } |
| 1457 | 1466 | ||
| 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 | } |
| 1467 | 1476 | ||
| ... | @@ -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(); |
| 1525 | 1534 | ||
| 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); |
| 1528 | 1537 | ||
| 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 | }; |
| 1541 | 1550 | ||
| 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 | } |
| 1550 | 1559 | ||
| ... | @@ -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 | } |
| 1578 | 1587 | ||
| ... | @@ -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 | } |
| 1632 | 1641 | ||
| ... | @@ -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 tripping | 1771 | /// 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, |
| 1792 | 1803 | ||
| ... | @@ -1804,6 +1815,7 @@ pub const DeclGen = struct { | ... | @@ -1804,6 +1815,7 @@ pub const DeclGen = struct { |
| 1804 | 1815 | ||
| 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); |
| 1808 | 1820 | ||
| 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); |
| 1870 | 1882 | ||
| 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 has | 1901 | /// 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; |
| 1894 | 1906 | 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.*; |
| 1898 | 1908 | ||
| 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 { |
| 1903 | 1913 | ||
| 1904 | const fn_type = try dg.llvmType(zig_fn_type); | 1914 | const fn_type = try dg.llvmType(zig_fn_type); |
| 1905 | 1915 | ||
| 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); |
| 1908 | 1918 | ||
| 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 attributes | 2006 | // TODO add target-cpu and target-features fn attributes |
| 1997 | } | 2007 | } |
| 1998 | 2008 | ||
| 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)); |
| 2003 | 2013 | ||
| 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); |
| 2006 | 2017 | ||
| 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.*; |
| 2127 | 2138 | ||
| 2128 | // The Type memory is ephemeral; since we want to store a longer-lived | 2139 | // 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()); |
| 2131 | 2142 | ||
| 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); |
| 2135 | 2146 | ||
| 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.*; |
| 2196 | 2207 | ||
| 2197 | // The Type memory is ephemeral; since we want to store a longer-lived | 2208 | // 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 | } |
| 2262 | 2273 | ||
| 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); |
| 2265 | 2276 | ||
| 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.*; |
| 2319 | 2330 | ||
| 2320 | // The Type memory is ephemeral; since we want to store a longer-lived | 2331 | // 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 | } |
| 2332 | 2343 | ||
| 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); |
| 2335 | 2346 | ||
| 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 handling | 2450 | // 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 top | 2451 | // 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 | }; |
| 3051 | 3064 | ||
| 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); |
| 3060 | 3079 | ||
| 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); |
| 3127 | 3145 | ||
| 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); |
| 3143 | 3161 | ||
| 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; |
| 3154 | 3172 | ||
| 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); |
| 3157 | 3175 | ||
| 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 pointer | 3177 | // 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); |
| 3174 | 3192 | ||
| 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); |
| 3177 | 3195 | ||
| 3178 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 3196 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 3179 | // In this case, we represent pointer to error union the same as pointer | 3197 | // 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 | } |
| 3242 | 3260 | ||
| 3243 | decl.markAlive(); | 3261 | self.module.markDeclAlive(decl); |
| 3244 | 3262 | ||
| 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 | else | 3265 | else |
| 3248 | try self.resolveGlobalDecl(decl); | 3266 | try self.resolveGlobalDecl(decl_index); |
| 3249 | 3267 | ||
| 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; |
| 4406 | 4424 | ||
| 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 | }); |
| 4419 | 4438 | ||
| 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); |
| 4422 | 4441 | ||
| 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; |
| 4448 | 4467 | ||
| 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); |
| 6432 | 6452 | ||
| 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 | }); |
| 6436 | 6457 | ||
| 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 { |
| 6617 | 6638 | ||
| 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 | } |
| 635 | 635 | ||
| 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 guarantees | 643 | // 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); |
| 646 | 652 | ||
| 647 | const target = self.getTarget(); | 653 | assert(self.air.typeOf(bin_op.lhs).eql(ty, self.module)); |
| 648 | 654 | 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)); | ||
| 651 | 655 | ||
| 652 | // Binary operations are generally applicable to both scalar and vector operations | 656 | // 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)); |
| 698 | 702 | ||
| 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 { |
| 90 | 90 | ||
| 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); | ||
| 93 | 95 | ||
| 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"); |
| 97 | 99 | ||
| 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, // indent | 106 | 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, // indent | 128 | 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 | } |
| 148 | 151 | ||
| 149 | fn writeFullyQualifiedDeclWithFile(decl: *Decl, stream: anytype) !void { | 152 | fn 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 | } |
| 154 | 157 | ||
| 155 | pub fn compilerPanic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) noreturn { | 158 | pub 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 unnamed | 417 | /// 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 section | 418 | /// 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: off | 424 | // 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: on | 433 | // zig fmt: on |
| 433 | } | 434 | } |
| ... | @@ -435,19 +436,20 @@ pub const File = struct { | ... | @@ -435,19 +436,20 @@ pub const File = struct { |
| 435 | 436 | ||
| 436 | /// May be called before or after updateDeclExports but must be called | 437 | /// 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: off | 444 | // 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: on | 453 | // 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 called | 457 | /// 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: off | 465 | // 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 having | 495 | /// TODO we're transitioning to deleting this function and instead having |
| 493 | /// each linker backend notice the first time updateDecl or updateFunc is called, or | 496 | /// 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 from | 505 | // 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 | } |
| 622 | 626 | ||
| 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 | } |
| 637 | 640 | ||
| ... | @@ -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 | } |
| 675 | 679 | ||
| ... | @@ -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's | 687 | /// 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 the | 688 | /// 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 it | 22 | /// 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. |
| 24 | decl_table: std.AutoArrayHashMapUnmanaged(*const Module.Decl, DeclBlock) = .{}, | 24 | decl_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(). |
| 27 | arena: std.heap.ArenaAllocator, | 27 | arena: 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 | } |
| 89 | 89 | ||
| 90 | pub fn freeDecl(self: *C, decl: *Module.Decl) void { | 90 | pub 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(); |
| 101 | 101 | ||
| 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 |
| 150 | 151 | ||
| 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 | } |
| 168 | 169 | ||
| 169 | pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void { | 170 | pub 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(); |
| 172 | 173 | ||
| 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); |
| 188 | 189 | ||
| 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 { |
| 211 | 215 | ||
| 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) |
| 287 | 291 | ||
| 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 | } |
| 294 | 298 | ||
| 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 | } |
| 299 | 303 | ||
| 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) |
| 305 | 309 | ||
| 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 | } |
| 326 | 331 | ||
| 327 | const Flush = struct { | 332 | const 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 | }; |
| 355 | 360 | ||
| 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. |
| 357 | fn flushDecl(self: *C, f: *Flush, decl: *const Module.Decl) FlushDeclError!void { | 362 | fn 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 its | 365 | // Before flushing any particular Decl we must ensure its |
| 359 | // dependencies are already flushed, so that the order in the .c | 366 | // 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 | } |
| 366 | 373 | ||
| 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; |
| 369 | 376 | ||
| 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 | }); |
| 419 | 428 | ||
| 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 { |
| 442 | pub fn updateDeclExports( | 451 | pub 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 | } |
| 420 | 420 | ||
| 421 | pub fn allocateDeclIndexes(self: *Coff, decl: *Module.Decl) !void { | 421 | pub fn allocateDeclIndexes(self: *Coff, decl_index: Module.Decl.Index) !void { |
| 422 | if (self.llvm_object) |_| return; | 422 | if (self.llvm_object) |_| return; |
| 423 | 423 | ||
| 424 | try self.offset_table.ensureUnusedCapacity(self.base.allocator, 1); | 424 | try self.offset_table.ensureUnusedCapacity(self.base.allocator, 1); |
| 425 | 425 | ||
| 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(); |
| 676 | 677 | ||
| 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 | } |
| 698 | 700 | ||
| 699 | pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl: *Module.Decl) !u32 { | 701 | pub 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 | } |
| 706 | 708 | ||
| 707 | pub fn updateDecl(self: *Coff, module: *Module, decl: *Module.Decl) !void { | 709 | pub 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(); |
| 716 | 718 | ||
| 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 | }; |
| 742 | 746 | ||
| 743 | return self.finishUpdateDecl(module, decl, code); | 747 | return self.finishUpdateDecl(module, decl_index, code); |
| 744 | } | 748 | } |
| 745 | 749 | ||
| 746 | fn finishUpdateDecl(self: *Coff, module: *Module, decl: *Module.Decl, code: []const u8) !void { | 750 | fn 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); |
| 779 | 784 | ||
| 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 | } |
| 784 | 789 | ||
| 785 | pub fn freeDecl(self: *Coff, decl: *Module.Decl) void { | 790 | pub 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 | } |
| 789 | 794 | ||
| 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 { |
| 795 | pub fn updateDeclExports( | 803 | pub 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 | } |
| 807 | 815 | ||
| 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 | } |
| 1476 | 1485 | ||
| 1477 | pub fn getDeclVAddr(self: *Coff, decl: *const Module.Decl, reloc_info: link.File.RelocInfo) !u64 { | 1486 | pub 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. |
| 68 | pub const DeclState = struct { | 68 | pub 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) = .{}, |
| 83 | 83 | ||
| 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(); |
| 158 | 158 | ||
| 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.data1 | 181 | // 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.string | 183 | // 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.data1 | 192 | // 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.string | 194 | // 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.string | 205 | // 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.member | 207 | // 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.sdata | 242 | // 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.string | 244 | // 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.member | 246 | // 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_type | 285 | // 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.string | 287 | // 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.ref4 | 289 | // 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.string | 314 | // 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)}); |
| 316 | 316 | ||
| 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.string | 333 | // 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.string | 374 | // 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); |
| 414 | 414 | ||
| 415 | // TODO this is temporary to match current state of unions in Zig - we don't yet have | 415 | // 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 generated | 416 | // 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.sdata | 507 | // 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.string | 509 | // 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}); |
| 512 | 512 | ||
| 513 | // DW.AT.member | 513 | // DW.AT.member |
| ... | @@ -654,17 +654,17 @@ pub fn deinit(self: *Dwarf) void { | ... | @@ -654,17 +654,17 @@ pub fn deinit(self: *Dwarf) void { |
| 654 | 654 | ||
| 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`. |
| 657 | pub fn initDeclState(self: *Dwarf, decl: *Module.Decl) !DeclState { | 657 | pub 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(); |
| 660 | 660 | ||
| 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); |
| 663 | 663 | ||
| 664 | log.debug("initDeclState {s}{*}", .{ decl_name, decl }); | 664 | log.debug("initDeclState {s}{*}", .{ decl_name, decl }); |
| 665 | 665 | ||
| 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.string | 2135 | // 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}); |
| 2138 | 2138 | ||
| 2139 | // DW.AT.enumerator | 2139 | // 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 allocated | 134 | /// 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. |
| 137 | decls: std.AutoHashMapUnmanaged(*Module.Decl, ?u16) = .{}, | 137 | decls: std.AutoHashMapUnmanaged(Module.Decl.Index, ?u16) = .{}, |
| 138 | 138 | ||
| 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 linking | 140 | /// 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 | }; |
| 179 | 179 | ||
| 180 | const RelocTable = std.AutoHashMapUnmanaged(*TextBlock, std.ArrayListUnmanaged(Reloc)); | 180 | const RelocTable = std.AutoHashMapUnmanaged(*TextBlock, std.ArrayListUnmanaged(Reloc)); |
| 181 | const UnnamedConstTable = std.AutoHashMapUnmanaged(*Module.Decl, std.ArrayListUnmanaged(*TextBlock)); | 181 | const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(*TextBlock)); |
| 182 | 182 | ||
| 183 | /// When allocating, the ideal_capacity is calculated by | 183 | /// 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 | } |
| 391 | 391 | ||
| 392 | pub fn getDeclVAddr(self: *Elf, decl: *const Module.Decl, reloc_info: File.RelocInfo) !u64 { | 392 | pub 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); |
| 395 | 398 | ||
| ... | @@ -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 | } |
| 2191 | 2194 | ||
| 2192 | pub fn allocateDeclIndexes(self: *Elf, decl: *Module.Decl) !void { | 2195 | pub fn allocateDeclIndexes(self: *Elf, decl_index: Module.Decl.Index) !void { |
| 2193 | if (self.llvm_object) |_| return; | 2196 | if (self.llvm_object) |_| return; |
| 2194 | 2197 | ||
| 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; |
| 2196 | 2201 | ||
| 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); |
| 2199 | 2204 | ||
| 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); |
| 2202 | 2207 | ||
| 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 | } |
| 2216 | 2221 | ||
| 2217 | fn freeUnnamedConsts(self: *Elf, decl: *Module.Decl) void { | 2222 | fn 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 | } |
| 2227 | 2232 | ||
| 2228 | pub fn freeDecl(self: *Elf, decl: *Module.Decl) void { | 2233 | pub 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 | } |
| 2232 | 2237 | ||
| 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 | } |
| 2238 | 2246 | ||
| 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 | } |
| 2276 | 2284 | ||
| 2277 | fn updateDeclCode(self: *Elf, decl: *Module.Decl, code: []const u8, stt_bits: u8) !*elf.Elf64_Sym { | 2285 | fn 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); |
| 2280 | 2291 | ||
| 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); |
| 2283 | 2294 | ||
| 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(); |
| 2357 | 2368 | ||
| 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); | ||
| 2360 | 2372 | ||
| 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(); |
| 2363 | 2375 | ||
| 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 | } |
| 2390 | 2402 | ||
| 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 | } |
| 2395 | 2407 | ||
| 2396 | pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void { | 2408 | pub 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 | } |
| 2403 | 2415 | ||
| 2404 | const tracy = trace(@src()); | 2416 | const tracy = trace(@src()); |
| 2405 | defer tracy.end(); | 2417 | defer tracy.end(); |
| 2406 | 2418 | ||
| 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 | } |
| 2416 | 2430 | ||
| 2417 | assert(!self.unnamed_const_atoms.contains(decl)); | 2431 | assert(!self.unnamed_const_atoms.contains(decl_index)); |
| 2418 | 2432 | ||
| 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(); |
| 2421 | 2435 | ||
| 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(); |
| 2424 | 2438 | ||
| 2425 | // TODO implement .debug_info for global variables | 2439 | // 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 | }; |
| 2453 | 2467 | ||
| 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 | } |
| 2465 | 2479 | ||
| 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 | } |
| 2470 | 2484 | ||
| 2471 | pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl: *Module.Decl) !u32 { | 2485 | pub 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(); |
| 2474 | 2488 | ||
| 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); |
| 2486 | 2502 | ||
| 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); |
| 2490 | 2506 | ||
| 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 |
| 2547 | pub fn updateDeclExports( | 2563 | pub 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 | } |
| 2559 | 2575 | ||
| 2560 | const tracy = trace(@src()); | 2576 | const tracy = trace(@src()); |
| 2561 | defer tracy.end(); | 2577 | defer tracy.end(); |
| 2562 | 2578 | ||
| 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]; |
| 2566 | 2583 | ||
| 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 | } |
| 2634 | 2651 | ||
| 2635 | /// Must be called only after a successful call to `updateDecl`. | 2652 | /// Must be called only after a successful call to `updateDecl`. |
| 2636 | pub fn updateDeclLineNumber(self: *Elf, module: *Module, decl: *const Module.Decl) !void { | 2653 | pub 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(); |
| 2640 | 2656 | ||
| 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); |
| 2643 | 2659 | ||
| 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 allocated | 247 | /// 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. |
| 250 | decls: std.AutoArrayHashMapUnmanaged(*Module.Decl, ?MatchingSection) = .{}, | 250 | decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, ?MatchingSection) = .{}, |
| 251 | 251 | ||
| 252 | const Entry = struct { | 252 | const Entry = struct { |
| 253 | target: Atom.Relocation.Target, | 253 | target: Atom.Relocation.Target, |
| 254 | atom: *Atom, | 254 | atom: *Atom, |
| 255 | }; | 255 | }; |
| 256 | 256 | ||
| 257 | const UnnamedConstTable = std.AutoHashMapUnmanaged(*Module.Decl, std.ArrayListUnmanaged(*Atom)); | 257 | const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(*Atom)); |
| 258 | 258 | ||
| 259 | const PendingUpdate = union(enum) { | 259 | const 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); | ||
| 3458 | 3463 | ||
| 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 | } |
| 3654 | 3659 | ||
| 3655 | pub fn allocateDeclIndexes(self: *MachO, decl: *Module.Decl) !void { | 3660 | pub 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; |
| 3658 | 3664 | ||
| 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); |
| 3662 | 3668 | ||
| 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(); |
| 3678 | 3684 | ||
| 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); | ||
| 3681 | 3688 | ||
| 3682 | // TODO clearing the code and relocs buffer should probably be orchestrated | 3689 | // TODO clearing the code and relocs buffer should probably be orchestrated |
| 3683 | // in a different, smarter, more automatic way somewhere else, in a more centralised | 3690 | // 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(); |
| 3691 | 3698 | ||
| 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 | else | 3701 | 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 | } |
| 3715 | 3722 | ||
| 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); |
| 3717 | 3724 | ||
| 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 |
| 3728 | 3735 | ||
| 3729 | // Since we updated the vaddr and the size, each corresponding export symbol also | 3736 | // 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 | } |
| 3734 | 3741 | ||
| 3735 | pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl: *Module.Decl) !u32 { | 3742 | pub 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(); |
| 3738 | 3745 | ||
| 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; |
| 3745 | 3752 | ||
| 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); |
| 3748 | 3756 | ||
| 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 | } |
| 3802 | 3810 | ||
| 3803 | pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { | 3811 | pub 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(); |
| 3812 | 3820 | ||
| 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(); |
| 3825 | 3835 | ||
| 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 | else | 3838 | 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); |
| 3871 | 3881 | ||
| 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 { |
| 3882 | 3892 | ||
| 3883 | // Since we updated the vaddr and the size, each corresponding export symbol also | 3893 | // 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 | } |
| 3888 | 3898 | ||
| 3889 | /// Checks if the value, or any of its embedded values stores a pointer, and thus requires | 3899 | /// 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. |
| 3891 | fn needsPointerRebase(ty: Type, val: Value, target: std.Target) bool { | 3901 | fn 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 { |
| 3942 | fn getMatchingSectionAtom(self: *MachO, atom: *Atom, name: []const u8, ty: Type, val: Value) !MatchingSection { | 3952 | fn 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 | } |
| 3971 | 3982 | ||
| 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 | } |
| 4027 | 4038 | ||
| 4028 | fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64 { | 4039 | fn 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]; |
| 4032 | 4045 | ||
| 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); |
| 4035 | 4048 | ||
| 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 |
| 4101 | pub fn updateDeclExports( | 4114 | pub 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(); |
| 4115 | 4128 | ||
| 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]; |
| 4119 | 4133 | ||
| ... | @@ -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 | } |
| 4252 | 4266 | ||
| 4253 | fn freeUnnamedConsts(self: *MachO, decl: *Module.Decl) void { | 4267 | fn 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 | } |
| 4269 | 4282 | ||
| 4270 | pub fn freeDecl(self: *MachO, decl: *Module.Decl) void { | 4283 | pub 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 | } |
| 4309 | 4324 | ||
| 4310 | pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl, reloc_info: File.RelocInfo) !u64 { | 4325 | pub 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); |
| 4313 | 4331 |
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 | } |
| 76 | 76 | ||
| 77 | pub fn updateDecl(self: *NvPtx, module: *Module, decl: *Module.Decl) !void { | 77 | pub 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 | } |
| 81 | 81 | ||
| 82 | pub fn updateDeclExports( | 82 | pub 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 | } |
| 94 | 94 | ||
| 95 | pub fn freeDecl(self: *NvPtx, decl: *Module.Decl) void { | 95 | pub 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 | } |
| 99 | 99 | ||
| 100 | pub fn flush(self: *NvPtx, comp: *Compilation, prog_node: *std.Progress.Node) !void { | 100 | pub 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) |
| 60 | fn_decl_table: std.AutoArrayHashMapUnmanaged( | 60 | fn_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 | ) = .{}, |
| 64 | data_decl_table: std.AutoArrayHashMapUnmanaged(*Module.Decl, []const u8) = .{}, | 64 | data_decl_table: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, []const u8) = .{}, |
| 65 | 65 | ||
| 66 | hdr: aout.ExecHdr = undefined, | 66 | hdr: aout.ExecHdr = undefined, |
| 67 | 67 | ||
| ... | @@ -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 | } |
| 164 | 164 | ||
| 165 | fn putFn(self: *Plan9, decl: *Module.Decl, out: FnDeclOutput) !void { | 165 | fn 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); |
| 182 | 184 | ||
| 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 | } |
| 231 | 233 | ||
| 232 | const decl = func.owner_decl; | 234 | const decl_index = func.owner_decl; |
| 235 | const decl = module.declPtr(decl_index); | ||
| 233 | 236 | ||
| 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 }); |
| 236 | 239 | ||
| 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 | } |
| 278 | 281 | ||
| 279 | pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl: *Module.Decl) !u32 { | 282 | pub 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 | } |
| 286 | 289 | ||
| 287 | pub fn updateDecl(self: *Plan9, module: *Module, decl: *Module.Decl) !void { | 290 | pub 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 | } |
| 297 | 302 | ||
| 298 | try self.seeDecl(decl); | 303 | try self.seeDecl(decl_index); |
| 299 | 304 | ||
| 300 | log.debug("codegen decl {*} ({s})", .{ decl, decl.name }); | 305 | log.debug("codegen decl {*} ({s})", .{ decl, decl.name }); |
| 301 | 306 | ||
| ... | @@ -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 }); |
| 488 | 495 | ||
| ... | @@ -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 | } |
| 566 | 573 | ||
| 567 | pub fn freeDecl(self: *Plan9, decl: *Module.Decl) void { | 574 | pub fn freeDecl(self: *Plan9, decl_index: Module.Decl.Index) void { |
| 568 | // TODO audit the lifetimes of decls table entries. It's possible to get | 575 | // 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.zig | 577 | // 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 length | 595 | // 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 | } |
| 595 | 603 | ||
| 596 | pub fn seeDecl(self: *Plan9, decl: *Module.Decl) !void { | 604 | pub 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 { |
| 607 | pub fn updateDeclExports( | 617 | pub 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 flush | 624 | // we do all the things in flush |
| 615 | _ = self; | 625 | _ = self; |
| 616 | _ = module; | 626 | _ = module; |
| 617 | _ = decl; | ||
| 618 | _ = exports; | 627 | _ = exports; |
| 619 | } | 628 | } |
| 620 | pub fn deinit(self: *Plan9) void { | 629 | pub 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 symbols | 724 | // 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 symbol | 750 | // 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 | } |
| 755 | 769 | ||
| 756 | /// this will be removed, moved to updateFinish | 770 | /// this will be removed, moved to updateFinish |
| 757 | pub fn allocateDeclIndexes(self: *Plan9, decl: *Module.Decl) !void { | 771 | pub fn allocateDeclIndexes(self: *Plan9, decl_index: Module.Decl.Index) !void { |
| 758 | _ = self; | 772 | _ = self; |
| 759 | _ = decl; | 773 | _ = decl_index; |
| 760 | } | 774 | } |
| 761 | pub fn getDeclVAddr(self: *Plan9, decl: *const Module.Decl, reloc_info: link.File.RelocInfo) !u64 { | 775 | pub 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 it | 55 | /// Instead, it tracks all declarations in this table, and iterates over it |
| 56 | /// in the flush function. | 56 | /// in the flush function. |
| 57 | decl_table: std.AutoArrayHashMapUnmanaged(*Module.Decl, DeclGenContext) = .{}, | 57 | decl_table: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclGenContext) = .{}, |
| 58 | 58 | ||
| 59 | const DeclGenContext = struct { | 59 | const 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 | } |
| 147 | 147 | ||
| 148 | pub fn updateDecl(self: *SpirV, module: *Module, decl: *Module.Decl) !void { | 148 | pub 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 | } |
| 156 | 156 | ||
| 157 | pub fn updateDeclExports( | 157 | pub 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 | } |
| 168 | 168 | ||
| 169 | pub fn freeDecl(self: *SpirV, decl: *Module.Decl) void { | 169 | pub 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 there | 210 | // 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 |
| 220 | 223 | ||
| 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; |
| 225 | 229 | ||
| 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 |
| 228 | 232 | ||
| 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 memory | 49 | /// This is ment for bookkeeping so we can safely cleanup all codegen memory |
| 50 | /// when calling `deinit` | 50 | /// when calling `deinit` |
| 51 | decls: std.AutoHashMapUnmanaged(*Module.Decl, void) = .{}, | 51 | decls: std.AutoHashMapUnmanaged(Module.Decl.Index, void) = .{}, |
| 52 | /// List of all symbols generated by Zig code. | 52 | /// List of all symbols generated by Zig code. |
| 53 | symbols: std.ArrayListUnmanaged(Symbol) = .{}, | 53 | symbols: 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 | } |
| 431 | 431 | ||
| 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 | } |
| 436 | 441 | ||
| 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 | } |
| 478 | 483 | ||
| 479 | pub fn allocateDeclIndexes(self: *Wasm, decl: *Module.Decl) !void { | 484 | pub 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; |
| 482 | 488 | ||
| 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, {}); |
| 485 | 491 | ||
| 486 | const atom = &decl.link.wasm; | 492 | const atom = &decl.link.wasm; |
| 487 | 493 | ||
| ... | @@ -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 | } |
| 504 | 510 | ||
| 505 | pub fn updateFunc(self: *Wasm, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void { | 511 | pub 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() |
| 514 | 521 | ||
| 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 |
| 540 | 547 | ||
| 541 | // Generate code for the Decl, storing it in memory to be later written to | 548 | // Generate code for the Decl, storing it in memory to be later written to |
| 542 | // the file on flush(). | 549 | // the file on flush(). |
| 543 | pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void { | 550 | pub 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 | } |
| 550 | 557 | ||
| 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() |
| 552 | 560 | ||
| 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 { |
| 590 | 598 | ||
| 591 | fn finishUpdateDecl(self: *Wasm, decl: *Module.Decl, code: []const u8) !void { | 599 | fn 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]; |
| 597 | 606 | ||
| 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 local | 616 | /// 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. |
| 609 | pub fn lowerUnnamedConst(self: *Wasm, decl: *Module.Decl, tv: TypedValue) !u32 { | 618 | pub fn lowerUnnamedConst(self: *Wasm, tv: TypedValue, decl_index: Module.Decl.Index) !u32 { |
| 610 | assert(tv.ty.zigTypeTag() != .Fn); // cannot create local symbols for functions | 619 | assert(tv.ty.zigTypeTag() != .Fn); // cannot create local symbols for functions |
| 611 | 620 | ||
| 621 | const mod = self.base.options.module.?; | ||
| 622 | const decl = mod.declPtr(decl_index); | ||
| 623 | |||
| 612 | // Create and initialize a new local symbol and atom | 624 | // 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(); |
| 643 | 655 | ||
| 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 address | 683 | /// Returns the given pointer address |
| 673 | pub fn getDeclVAddr( | 684 | pub 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 { |
| 722 | 735 | ||
| 723 | pub fn updateDeclExports( | 736 | pub 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 | } |
| 735 | 748 | ||
| 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 times | 775 | \\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 | } |
| 775 | 790 | ||
| 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 default | 803 | .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 | } |
| 815 | 831 | ||
| 816 | pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void { | 832 | pub 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 { |
| 1414 | 1432 | ||
| 1415 | // Addend for each relocation to the table | 1433 | // 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-termianted | 1437 | const len = @intCast(u32, error_name.len + 1); // names are 0-termianted |
| 1420 | 1438 | ||
| 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; |
| 1464 | 1484 | ||
| ... | @@ -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) ! |
| 2045 | 2067 | ||
| 2046 | // If there is no Zig code to compile, then we should skip flushing the output file because it | 2068 | // 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 | } |
| 2254 | 2276 | ||
| 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 and | 2287 | 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 command | 2293 | // skip exporting symbols when we're building a WASI command |
| 2271 | // and the symbol is not a function | 2294 | // 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 | }; |
| 3897 | 3897 | ||
| 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 | }; |
| 4103 | 4103 | ||
| 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 | }; |
| 4915 | 4915 | ||
| 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; |
| 7 | const Air = @import("Air.zig"); | 7 | const Air = @import("Air.zig"); |
| 8 | const Liveness = @import("Liveness.zig"); | 8 | const Liveness = @import("Liveness.zig"); |
| 9 | 9 | ||
| 10 | pub fn dump(gpa: Allocator, air: Air, liveness: Liveness) void { | 10 | pub 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 include | 12 | // 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: on | 43 | // 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(); |
| 46 | 46 | ||
| 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 | } |
| 59 | 60 | ||
| 60 | const Writer = struct { | 61 | const 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 | } |
| 596 | 599 | ||
| 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 | } |
| 523 | 523 | ||
| 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; |
| 527 | 527 | ||
| ... | @@ -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(); |
| 639 | 639 | ||
| 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; |
| 642 | 642 | ||
| 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; |
| 665 | 665 | ||
| 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 | } |
| 669 | 669 | ||
| ... | @@ -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 { |
| 718 | 718 | ||
| 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 { |
| 762 | 762 | ||
| 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 | }, |
| 767 | 767 | ||
| 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 { |
| 770 | 770 | ||
| 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; |
| 774 | 774 | ||
| 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; |
| 778 | 778 | ||
| 779 | return true; | 779 | return true; |
| 780 | }, | 780 | }, |
| 781 | 781 | ||
| 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 | }, |
| 786 | 786 | ||
| 787 | .empty_struct => { | 787 | .empty_struct => { |
| ... | @@ -804,7 +804,7 @@ pub const Type = extern union { | ... | @@ -804,7 +804,7 @@ pub const Type = extern union { |
| 804 | 804 | ||
| 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 | } |
| 809 | 809 | ||
| 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 { |
| 840 | 840 | ||
| 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 | } |
| 845 | 845 | ||
| 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 | } |
| 913 | 913 | ||
| 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 | } |
| 919 | 919 | ||
| 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, |
| 923 | 923 | ||
| ... | @@ -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); |
| 1037 | 1037 | ||
| 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 | }, |
| 1052 | 1052 | ||
| ... | @@ -1059,8 +1059,8 @@ pub const Type = extern union { | ... | @@ -1059,8 +1059,8 @@ pub const Type = extern union { |
| 1059 | 1059 | ||
| 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 | }, |
| 1065 | 1065 | ||
| 1066 | .vector => { | 1066 | .vector => { |
| ... | @@ -1068,7 +1068,7 @@ pub const Type = extern union { | ... | @@ -1068,7 +1068,7 @@ pub const Type = extern union { |
| 1068 | 1068 | ||
| 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 | }, |
| 1073 | 1073 | ||
| 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); |
| 1093 | 1093 | ||
| 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); |
| 1112 | 1112 | ||
| 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 | }, |
| 1116 | 1116 | ||
| 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); |
| 1119 | 1119 | ||
| 1120 | const set_ty = ty.errorUnionSet(); | 1120 | const set_ty = ty.errorUnionSet(); |
| 1121 | hashWithHasher(set_ty, hasher, target); | 1121 | hashWithHasher(set_ty, hasher, mod); |
| 1122 | 1122 | ||
| 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 | }, |
| 1126 | 1126 | ||
| 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 | }, |
| 1131 | 1131 | ||
| 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); |
| 1146 | 1146 | ||
| 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 | }, |
| 1168 | 1168 | ||
| ... | @@ -1210,35 +1210,35 @@ pub const Type = extern union { | ... | @@ -1210,35 +1210,35 @@ pub const Type = extern union { |
| 1210 | } | 1210 | } |
| 1211 | } | 1211 | } |
| 1212 | 1212 | ||
| 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 | } |
| 1221 | 1221 | ||
| 1222 | pub const HashContext64 = struct { | 1222 | pub const HashContext64 = struct { |
| 1223 | target: Target, | 1223 | mod: *Module, |
| 1224 | 1224 | ||
| 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 | }; |
| 1232 | 1232 | ||
| 1233 | pub const HashContext32 = struct { | 1233 | pub const HashContext32 = struct { |
| 1234 | target: Target, | 1234 | mod: *Module, |
| 1235 | 1235 | ||
| 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 | }; |
| 1244 | 1244 | ||
| ... | @@ -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 | } |
| 1485 | 1485 | ||
| 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 | } |
| 1492 | 1492 | ||
| 1493 | const FormatContext = struct { | 1493 | const FormatContext = struct { |
| 1494 | ty: Type, | 1494 | ty: Type, |
| 1495 | target: Target, | 1495 | module: *Module, |
| 1496 | }; | 1496 | }; |
| 1497 | 1497 | ||
| 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 | } |
| 1508 | 1508 | ||
| 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 { |
| 1579 | 1579 | ||
| 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 name | 1611 | 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 | }, |
| 1604 | 1616 | ||
| 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 { |
| 1871 | 1885 | ||
| 1872 | pub const nameAllocArena = nameAlloc; | 1886 | pub const nameAllocArena = nameAlloc; |
| 1873 | 1887 | ||
| 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 | } |
| 1880 | 1894 | ||
| 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 { |
| 1946 | 1960 | ||
| 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 | }, |
| 1951 | 1965 | ||
| 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 | }, |
| 1976 | 1996 | ||
| 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; |
| 1991 | 2011 | ||
| 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 | }, |
| 1996 | 2017 | ||
| ... | @@ -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 | }, |
| 2021 | 2042 | ||
| 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 | }, |
| 2028 | 2049 | ||
| 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(": "); |
| 2085 | 2106 | ||
| 2086 | try print(field_ty, writer, target); | 2107 | try print(field_ty, writer, mod); |
| 2087 | 2108 | ||
| 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 { |
| 2106 | 2127 | ||
| 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 "); |
| 2131 | 2152 | ||
| 2132 | try print(info.pointee_type, writer, target); | 2153 | try print(info.pointee_type, writer, mod); |
| 2133 | }, | 2154 | }, |
| 2134 | 2155 | ||
| 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 *T | 3855 | /// For [*]T, returns *T |
| 3835 | /// For []T, returns *T | 3856 | /// 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 | } |
| 3950 | 3971 | ||
| 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` or | 4991 | /// 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 in | 4992 | /// 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 | } |
| 5226 | 5247 | ||
| 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 | } |
| 5230 | 5251 | ||
| 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 | } |
| 5270 | 5294 | ||
| 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 | } |
| 5358 | 5382 | ||
| 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"); |
| 5939 | 5963 | ||
| 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; |
| 5942 | 5968 | ||
| 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) and | 6099 | 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 | } |
| 800 | 800 | ||
| 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 | } |
| 807 | 807 | ||
| 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 | } |
| 838 | 840 | ||
| 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 { |
| 1975 | 1977 | ||
| 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 | } |
| 1990 | 1992 | ||
| 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 | } |
| 1999 | 2007 | ||
| 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 complication | 2047 | /// 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 - specifically | 2048 | /// 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; |
| 2061 | 2077 | ||
| 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); |
| 2064 | 2080 | ||
| 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; |
| 2071 | 2087 | ||
| 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; |
| 2078 | 2094 | ||
| 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]; |
| 2124 | 2140 | ||
| 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 compare | 2152 | // 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 { |
| 2225 | 2241 | ||
| 2226 | /// This function is used by hash maps and so treats floating-point NaNs as equal | 2242 | /// 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 { |
| 2242 | 2258 | ||
| 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 | }, |
| 2269 | 2285 | ||
| 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-null | 2331 | 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); // error | 2336 | 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 | } |
| 2325 | 2341 | ||
| 2326 | if (val.castTag(.eu_payload)) |payload| { | 2342 | if (val.castTag(.eu_payload)) |payload| { |
| 2327 | std.hash.autoHash(hasher, true); // payload | 2343 | 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 { |
| 2372 | 2388 | ||
| 2373 | pub const ArrayHashContext = struct { | 2389 | pub const ArrayHashContext = struct { |
| 2374 | ty: Type, | 2390 | ty: Type, |
| 2375 | target: Target, | 2391 | mod: *Module, |
| 2376 | 2392 | ||
| 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 | }; |
| 2386 | 2402 | ||
| 2387 | pub const HashContext = struct { | 2403 | pub const HashContext = struct { |
| 2388 | ty: Type, | 2404 | ty: Type, |
| 2389 | target: Target, | 2405 | mod: *Module, |
| 2390 | 2406 | ||
| 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 | } |
| 2396 | 2412 | ||
| 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 | }; |
| 2401 | 2417 | ||
| ... | @@ -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 point | 2450 | /// 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 | }, |
| 2468 | 2484 | ||
| ... | @@ -2505,53 +2521,6 @@ pub const Value = extern union { | ... | @@ -2505,53 +2521,6 @@ pub const Value = extern union { |
| 2505 | } | 2521 | } |
| 2506 | } | 2522 | } |
| 2507 | 2523 | ||
| 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 | } |
| 2563 | 2532 | ||
| 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 { |
| 2599 | 2569 | ||
| 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 | } |
| 2605 | 2575 | ||
| 2606 | pub const ElemValueBuffer = Payload.U64; | 2576 | pub const ElemValueBuffer = Payload.U64; |
| 2607 | 2577 | ||
| 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 | } |
| 2611 | 2581 | ||
| 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, |
| 2644 | 2615 | ||
| 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), |
| 2647 | 2618 | ||
| 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 | }, |
| 2654 | 2625 | ||
| 2655 | // The child type of arrays which have only one possible value need | 2626 | // 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 | } |
| 2662 | 2633 | ||
| 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), |
| 2670 | 2647 | ||
| 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 | }, |
| 2677 | 2654 | ||
| 2678 | .repeated, | 2655 | .repeated, |
| ... | @@ -2718,7 +2695,13 @@ pub const Value = extern union { | ... | @@ -2718,7 +2695,13 @@ pub const Value = extern union { |
| 2718 | } | 2695 | } |
| 2719 | 2696 | ||
| 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 { |
| 2727 | 2710 | ||
| 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 { |
| 5059 | 5042 | ||
| 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 | }; |
| 5064 | 5047 | ||
| 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, |
| 5080 | 5063 | ||
| 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 { |
| 5215 | 5198 | ||
| 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 | }, |