authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-18 20:09:29-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-18 20:09:29-07:00
log9010bd8aec612d5a14e4be800c80b72025fac2c5
treec286b41d6b9d3131539586d75a22b91301a1d23d
parent29daf10639149bd023db0be4e04eaf154dce0f83

stage2: astgen: fix most of the remaining compile errors

more progress on converting astgen to the new AST memory layout. only a few code paths left to update.

7 files changed, 1052 insertions(+), 823 deletions(-)

lib/std/zig/ast.zig+10-30
...@@ -1754,25 +1754,20 @@ pub const Tree = struct {...@@ -1754,25 +1754,20 @@ pub const Tree = struct {
1754 const token_tags = tree.tokens.items(.tag);1754 const token_tags = tree.tokens.items(.tag);
1755 // TODO: looks like stage1 isn't quite smart enough to handle enum1755 // TODO: looks like stage1 isn't quite smart enough to handle enum
1756 // literals in some places here1756 // literals in some places here
1757 const Kind = full.PtrType.Kind;1757 const Size = std.builtin.TypeInfo.Pointer.Size;
1758 const kind: Kind = switch (token_tags[info.main_token]) {1758 const size: Size = switch (token_tags[info.main_token]) {
1759 .asterisk,1759 .asterisk,
1760 .asterisk_asterisk,1760 .asterisk_asterisk,
1761 => switch (token_tags[info.main_token + 1]) {1761 => switch (token_tags[info.main_token + 1]) {
1762 .r_bracket => .many,1762 .r_bracket, .colon => .Many,
1763 .colon => .sentinel,1763 .identifier => if (token_tags[info.main_token - 1] == .l_bracket) Size.C else .One,
1764 .identifier => if (token_tags[info.main_token - 1] == .l_bracket) Kind.c else .one,1764 else => .One,
1765 else => .one,
1766 },
1767 .l_bracket => switch (token_tags[info.main_token + 1]) {
1768 .r_bracket => Kind.slice,
1769 .colon => .slice_sentinel,
1770 else => unreachable,
1771 },1765 },
1766 .l_bracket => Size.Slice,
1772 else => unreachable,1767 else => unreachable,
1773 };1768 };
1774 var result: full.PtrType = .{1769 var result: full.PtrType = .{
1775 .kind = kind,1770 .size = size,
1776 .allowzero_token = null,1771 .allowzero_token = null,
1777 .const_token = null,1772 .const_token = null,
1778 .volatile_token = null,1773 .volatile_token = null,
...@@ -1782,13 +1777,7 @@ pub const Tree = struct {...@@ -1782,13 +1777,7 @@ pub const Tree = struct {
1782 // here while looking for modifiers as that could result in false1777 // here while looking for modifiers as that could result in false
1783 // positives. Therefore, start after a sentinel if there is one and1778 // positives. Therefore, start after a sentinel if there is one and
1784 // skip over any align node and bit range nodes.1779 // skip over any align node and bit range nodes.
1785 var i = if (kind == .sentinel or kind == .slice_sentinel) blk: {1780 var i = if (info.sentinel != 0) tree.lastToken(info.sentinel) + 1 else info.main_token;
1786 assert(info.sentinel != 0);
1787 break :blk tree.lastToken(info.sentinel) + 1;
1788 } else blk: {
1789 assert(info.sentinel == 0);
1790 break :blk info.main_token;
1791 };
1792 const end = tree.firstToken(info.child_type);1781 const end = tree.firstToken(info.child_type);
1793 while (i < end) : (i += 1) {1782 while (i < end) : (i += 1) {
1794 switch (token_tags[i]) {1783 switch (token_tags[i]) {
...@@ -2115,7 +2104,7 @@ pub const full = struct {...@@ -2115,7 +2104,7 @@ pub const full = struct {
2115 .comptime_noalias = comptime_noalias,2104 .comptime_noalias = comptime_noalias,
2116 .name_token = name_token,2105 .name_token = name_token,
2117 .anytype_ellipsis3 = it.tok_i - 1,2106 .anytype_ellipsis3 = it.tok_i - 1,
2118 .type_expr = param_type,2107 .type_expr = 0,
2119 };2108 };
2120 }2109 }
2121 it.tok_flag = false;2110 it.tok_flag = false;
...@@ -2166,21 +2155,12 @@ pub const full = struct {...@@ -2166,21 +2155,12 @@ pub const full = struct {
2166 };2155 };
21672156
2168 pub const PtrType = struct {2157 pub const PtrType = struct {
2169 kind: Kind,2158 size: std.builtin.TypeInfo.Pointer.Size,
2170 allowzero_token: ?TokenIndex,2159 allowzero_token: ?TokenIndex,
2171 const_token: ?TokenIndex,2160 const_token: ?TokenIndex,
2172 volatile_token: ?TokenIndex,2161 volatile_token: ?TokenIndex,
2173 ast: Ast,2162 ast: Ast,
21742163
2175 pub const Kind = enum {
2176 one,
2177 many,
2178 sentinel,
2179 c,
2180 slice,
2181 slice_sentinel,
2182 };
2183
2184 pub const Ast = struct {2164 pub const Ast = struct {
2185 main_token: TokenIndex,2165 main_token: TokenIndex,
2186 align_node: Node.Index,2166 align_node: Node.Index,
lib/std/zig/render.zig+25-23
...@@ -677,8 +677,8 @@ fn renderPtrType(...@@ -677,8 +677,8 @@ fn renderPtrType(
677 ptr_type: ast.full.PtrType,677 ptr_type: ast.full.PtrType,
678 space: Space,678 space: Space,
679) Error!void {679) Error!void {
680 switch (ptr_type.kind) {680 switch (ptr_type.size) {
681 .one => {681 .One => {
682 // Since ** tokens exist and the same token is shared by two682 // Since ** tokens exist and the same token is shared by two
683 // nested pointer types, we check to see if we are the parent683 // nested pointer types, we check to see if we are the parent
684 // in such a relationship. If so, skip rendering anything for684 // in such a relationship. If so, skip rendering anything for
...@@ -691,33 +691,35 @@ fn renderPtrType(...@@ -691,33 +691,35 @@ fn renderPtrType(
691 }691 }
692 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk692 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk
693 },693 },
694 .many => {694 .Many => {
695 try renderToken(ais, tree, ptr_type.ast.main_token - 1, .none); // lbracket695 if (ptr_type.ast.sentinel == 0) {
696 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk696 try renderToken(ais, tree, ptr_type.ast.main_token - 1, .none); // lbracket
697 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // rbracket697 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk
698 },698 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // rbracket
699 .sentinel => {699 } else {
700 try renderToken(ais, tree, ptr_type.ast.main_token - 1, .none); // lbracket700 try renderToken(ais, tree, ptr_type.ast.main_token - 1, .none); // lbracket
701 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk701 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk
702 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // colon702 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // colon
703 try renderExpression(ais, tree, ptr_type.ast.sentinel, .none);703 try renderExpression(ais, tree, ptr_type.ast.sentinel, .none);
704 try renderToken(ais, tree, tree.lastToken(ptr_type.ast.sentinel) + 1, .none); // rbracket704 try renderToken(ais, tree, tree.lastToken(ptr_type.ast.sentinel) + 1, .none); // rbracket
705 }
705 },706 },
706 .c => {707 .C => {
707 try renderToken(ais, tree, ptr_type.ast.main_token - 1, .none); // lbracket708 try renderToken(ais, tree, ptr_type.ast.main_token - 1, .none); // lbracket
708 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk709 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk
709 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // c710 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // c
710 try renderToken(ais, tree, ptr_type.ast.main_token + 2, .none); // rbracket711 try renderToken(ais, tree, ptr_type.ast.main_token + 2, .none); // rbracket
711 },712 },
712 .slice => {713 .Slice => {
713 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // lbracket714 if (ptr_type.ast.sentinel == 0) {
714 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // rbracket715 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // lbracket
715 },716 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // rbracket
716 .slice_sentinel => {717 } else {
717 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // lbracket718 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // lbracket
718 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // colon719 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // colon
719 try renderExpression(ais, tree, ptr_type.ast.sentinel, .none);720 try renderExpression(ais, tree, ptr_type.ast.sentinel, .none);
720 try renderToken(ais, tree, tree.lastToken(ptr_type.ast.sentinel) + 1, .none); // rbracket721 try renderToken(ais, tree, tree.lastToken(ptr_type.ast.sentinel) + 1, .none); // rbracket
722 }
721 },723 },
722 }724 }
723725
src/BuiltinFn.zig+523-520
...@@ -115,727 +115,730 @@ allows_lvalue: bool = false,...@@ -115,727 +115,730 @@ allows_lvalue: bool = false,
115/// of parameters.115/// of parameters.
116param_count: ?u8,116param_count: ?u8,
117117
118pub const list = std.ComptimeStringMap(@This(), .{118pub const list = list: {
119 .{119 @setEvalBranchQuota(3000);
120 "@addWithOverflow",120 break :list std.ComptimeStringMap(@This(), .{
121 .{121 .{
122 .tag = .add_with_overflow,122 "@addWithOverflow",
123 .param_count = 4,123 .{
124 .tag = .add_with_overflow,
125 .param_count = 4,
126 },
124 },127 },
125 },
126 .{
127 "@alignCast",
128 .{128 .{
129 .tag = align_cast,129 "@alignCast",
130 .param_count = 1,130 .{
131 .tag = .align_cast,
132 .param_count = 1,
133 },
131 },134 },
132 },
133 .{
134 "@alignOf",
135 .{135 .{
136 .tag = .align_of,136 "@alignOf",
137 .param_count = 1,137 .{
138 .tag = .align_of,
139 .param_count = 1,
140 },
138 },141 },
139 },
140 .{
141 "@as",
142 .{142 .{
143 .tag = .as,143 "@as",
144 .needs_mem_loc = true,144 .{
145 .param_count = 2,145 .tag = .as,
146 .needs_mem_loc = true,
147 .param_count = 2,
148 },
146 },149 },
147 },
148 .{
149 "@asyncCall",
150 .{150 .{
151 .tag = .async_call,151 "@asyncCall",
152 .param_count = null,152 .{
153 .tag = .async_call,
154 .param_count = null,
155 },
153 },156 },
154 },
155 .{
156 "@atomicLoad",
157 .{157 .{
158 .tag = .atomic_load,158 "@atomicLoad",
159 .param_count = 3,159 .{
160 .tag = .atomic_load,
161 .param_count = 3,
162 },
160 },163 },
161 },
162 .{
163 "@atomicRmw",
164 .{164 .{
165 .tag = .atomic_rmw,165 "@atomicRmw",
166 .param_count = 5,166 .{
167 .tag = .atomic_rmw,
168 .param_count = 5,
169 },
167 },170 },
168 },
169 .{
170 "@atomicStore",
171 .{171 .{
172 .tag = .atomic_store,172 "@atomicStore",
173 .param_count = 4,173 .{
174 .tag = .atomic_store,
175 .param_count = 4,
176 },
174 },177 },
175 },
176 .{
177 "@bitCast",
178 .{178 .{
179 .tag = .bit_cast,179 "@bitCast",
180 .needs_mem_loc = true,180 .{
181 .param_count = 2,181 .tag = .bit_cast,
182 .needs_mem_loc = true,
183 .param_count = 2,
184 },
182 },185 },
183 },
184 .{
185 "@bitOffsetOf",
186 .{186 .{
187 .tag = .bit_offset_of,187 "@bitOffsetOf",
188 .param_count = 2,188 .{
189 .tag = .bit_offset_of,
190 .param_count = 2,
191 },
189 },192 },
190 },
191 .{
192 "@boolToInt",
193 .{193 .{
194 .tag = .bool_to_int,194 "@boolToInt",
195 .param_count = 1,195 .{
196 .tag = .bool_to_int,
197 .param_count = 1,
198 },
196 },199 },
197 },
198 .{
199 "@bitSizeOf",
200 .{200 .{
201 .tag = .bit_size_of,201 "@bitSizeOf",
202 .param_count = 1,202 .{
203 .tag = .bit_size_of,
204 .param_count = 1,
205 },
203 },206 },
204 },
205 .{
206 "@breakpoint",
207 .{207 .{
208 .tag = .breakpoint,208 "@breakpoint",
209 .param_count = 0,209 .{
210 .tag = .breakpoint,
211 .param_count = 0,
212 },
210 },213 },
211 },
212 .{
213 "@mulAdd",
214 .{214 .{
215 .tag = .mul_add,215 "@mulAdd",
216 .param_count = 4,216 .{
217 .tag = .mul_add,
218 .param_count = 4,
219 },
217 },220 },
218 },
219 .{
220 "@byteSwap",
221 .{221 .{
222 .tag = .byte_swap,222 "@byteSwap",
223 .param_count = 2,223 .{
224 .tag = .byte_swap,
225 .param_count = 2,
226 },
224 },227 },
225 },
226 .{
227 "@bitReverse",
228 .{228 .{
229 .tag = .bit_reverse,229 "@bitReverse",
230 .param_count = 2,230 .{
231 .tag = .bit_reverse,
232 .param_count = 2,
233 },
231 },234 },
232 },
233 .{
234 "@byteOffsetOf",
235 .{235 .{
236 .tag = .byte_offset_of,236 "@byteOffsetOf",
237 .param_count = 2,237 .{
238 .tag = .byte_offset_of,
239 .param_count = 2,
240 },
238 },241 },
239 },
240 .{
241 "@call",
242 .{242 .{
243 .tag = .call,243 "@call",
244 .needs_mem_loc = true,244 .{
245 .param_count = 3,245 .tag = .call,
246 .needs_mem_loc = true,
247 .param_count = 3,
248 },
246 },249 },
247 },
248 .{
249 "@cDefine",
250 .{250 .{
251 .tag = .c_define,251 "@cDefine",
252 .param_count = 2,252 .{
253 .tag = .c_define,
254 .param_count = 2,
255 },
253 },256 },
254 },
255 .{
256 "@cImport",
257 .{257 .{
258 .tag = .c_import,258 "@cImport",
259 .param_count = 1,259 .{
260 .tag = .c_import,
261 .param_count = 1,
262 },
260 },263 },
261 },
262 .{
263 "@cInclude",
264 .{264 .{
265 .tag = .c_include,265 "@cInclude",
266 .param_count = 1,266 .{
267 .tag = .c_include,
268 .param_count = 1,
269 },
267 },270 },
268 },
269 .{
270 "@clz",
271 .{271 .{
272 .tag = .clz,272 "@clz",
273 .param_count = 2,273 .{
274 .tag = .clz,
275 .param_count = 2,
276 },
274 },277 },
275 },
276 .{
277 "@cmpxchgStrong",
278 .{278 .{
279 .tag = .cmpxchg_strong,279 "@cmpxchgStrong",
280 .param_count = 6,280 .{
281 .tag = .cmpxchg_strong,
282 .param_count = 6,
283 },
281 },284 },
282 },
283 .{
284 "@cmpxchgWeak",
285 .{285 .{
286 .tag = .cmpxchg_weak,286 "@cmpxchgWeak",
287 .param_count = 6,287 .{
288 .tag = .cmpxchg_weak,
289 .param_count = 6,
290 },
288 },291 },
289 },
290 .{
291 "@compileError",
292 .{292 .{
293 .tag = .compile_error,293 "@compileError",
294 .param_count = 1,294 .{
295 .tag = .compile_error,
296 .param_count = 1,
297 },
295 },298 },
296 },
297 .{
298 "@compileLog",
299 .{299 .{
300 .tag = .compile_log,300 "@compileLog",
301 .param_count = null,301 .{
302 .tag = .compile_log,
303 .param_count = null,
304 },
302 },305 },
303 },
304 .{
305 "@ctz",
306 .{306 .{
307 .tag = .ctz,307 "@ctz",
308 .param_count = 2,308 .{
309 .tag = .ctz,
310 .param_count = 2,
311 },
309 },312 },
310 },
311 .{
312 "@cUndef",
313 .{313 .{
314 .tag = .c_undef,314 "@cUndef",
315 .param_count = 1,315 .{
316 .tag = .c_undef,
317 .param_count = 1,
318 },
316 },319 },
317 },
318 .{
319 "@divExact",
320 .{320 .{
321 .tag = .div_exact,321 "@divExact",
322 .param_count = 2,322 .{
323 .tag = .div_exact,
324 .param_count = 2,
325 },
323 },326 },
324 },
325 .{
326 "@divFloor",
327 .{327 .{
328 .tag = .div_floor,328 "@divFloor",
329 .param_count = 2,329 .{
330 .tag = .div_floor,
331 .param_count = 2,
332 },
330 },333 },
331 },
332 .{
333 "@divTrunc",
334 .{334 .{
335 .tag = .div_trunc,335 "@divTrunc",
336 .param_count = 2,336 .{
337 .tag = .div_trunc,
338 .param_count = 2,
339 },
337 },340 },
338 },
339 .{
340 "@embedFile",
341 .{341 .{
342 .tag = .embed_file,342 "@embedFile",
343 .param_count = 1,343 .{
344 .tag = .embed_file,
345 .param_count = 1,
346 },
344 },347 },
345 },
346 .{
347 "@enumToInt",
348 .{348 .{
349 .tag = .enum_to_int,349 "@enumToInt",
350 .param_count = 1,350 .{
351 .tag = .enum_to_int,
352 .param_count = 1,
353 },
351 },354 },
352 },
353 .{
354 "@errorName",
355 .{355 .{
356 .tag = .error_name,356 "@errorName",
357 .param_count = 1,357 .{
358 .tag = .error_name,
359 .param_count = 1,
360 },
358 },361 },
359 },
360 .{
361 "@errorReturnTrace",
362 .{362 .{
363 .tag = .error_return_trace,363 "@errorReturnTrace",
364 .param_count = 0,364 .{
365 .tag = .error_return_trace,
366 .param_count = 0,
367 },
365 },368 },
366 },
367 .{
368 "@errorToInt",
369 .{369 .{
370 .tag = .error_to_int,370 "@errorToInt",
371 .param_count = 1,371 .{
372 .tag = .error_to_int,
373 .param_count = 1,
374 },
372 },375 },
373 },
374 .{
375 "@errSetCast",
376 .{376 .{
377 .tag = .err_set_cast,377 "@errSetCast",
378 .param_count = 2,378 .{
379 .tag = .err_set_cast,
380 .param_count = 2,
381 },
379 },382 },
380 },
381 .{
382 "@export",
383 .{383 .{
384 .tag = .@"export",384 "@export",
385 .param_count = 2,385 .{
386 .tag = .@"export",
387 .param_count = 2,
388 },
386 },389 },
387 },
388 .{
389 "@fence",
390 .{390 .{
391 .tag = .fence,391 "@fence",
392 .param_count = 0,392 .{
393 .tag = .fence,
394 .param_count = 0,
395 },
393 },396 },
394 },
395 .{
396 "@field",
397 .{397 .{
398 .tag = .field,398 "@field",
399 .needs_mem_loc = true,399 .{
400 .param_count = 2,400 .tag = .field,
401 .allows_lvalue = true,401 .needs_mem_loc = true,
402 .param_count = 2,
403 .allows_lvalue = true,
404 },
402 },405 },
403 },
404 .{
405 "@fieldParentPtr",
406 .{406 .{
407 .tag = .field_parent_ptr,407 "@fieldParentPtr",
408 .param_count = 3,408 .{
409 .tag = .field_parent_ptr,
410 .param_count = 3,
411 },
409 },412 },
410 },
411 .{
412 "@floatCast",
413 .{413 .{
414 .tag = .float_cast,414 "@floatCast",
415 .param_count = 1,415 .{
416 .tag = .float_cast,
417 .param_count = 1,
418 },
416 },419 },
417 },
418 .{
419 "@floatToInt",
420 .{420 .{
421 .tag = .float_to_int,421 "@floatToInt",
422 .param_count = 1,422 .{
423 .tag = .float_to_int,
424 .param_count = 1,
425 },
423 },426 },
424 },
425 .{
426 "@frame",
427 .{427 .{
428 .tag = .frame,428 "@frame",
429 .param_count = 0,429 .{
430 .tag = .frame,
431 .param_count = 0,
432 },
430 },433 },
431 },
432 .{
433 "@Frame",
434 .{434 .{
435 .tag = .Frame,435 "@Frame",
436 .param_count = 1,436 .{
437 .tag = .Frame,
438 .param_count = 1,
439 },
437 },440 },
438 },
439 .{
440 "@frameAddress",
441 .{441 .{
442 .tag = .frame_address,442 "@frameAddress",
443 .param_count = 0,443 .{
444 .tag = .frame_address,
445 .param_count = 0,
446 },
444 },447 },
445 },
446 .{
447 "@frameSize",
448 .{448 .{
449 .tag = .frame_size,449 "@frameSize",
450 .param_count = 1,450 .{
451 .tag = .frame_size,
452 .param_count = 1,
453 },
451 },454 },
452 },
453 .{
454 "@hasDecl",
455 .{455 .{
456 .tag = .has_decl,456 "@hasDecl",
457 .param_count = 2,457 .{
458 .tag = .has_decl,
459 .param_count = 2,
460 },
458 },461 },
459 },
460 .{
461 "@hasField",
462 .{462 .{
463 .tag = .has_field,463 "@hasField",
464 .param_count = 2,464 .{
465 .tag = .has_field,
466 .param_count = 2,
467 },
465 },468 },
466 },
467 .{
468 "@import",
469 .{469 .{
470 .tag = .import,470 "@import",
471 .param_count = 1,471 .{
472 .tag = .import,
473 .param_count = 1,
474 },
472 },475 },
473 },
474 .{
475 "@intCast",
476 .{476 .{
477 .tag = .int_cast,477 "@intCast",
478 .param_count = 1,478 .{
479 .tag = .int_cast,
480 .param_count = 1,
481 },
479 },482 },
480 },
481 .{
482 "@intToEnum",
483 .{483 .{
484 .tag = .int_to_enum,484 "@intToEnum",
485 .param_count = 1,485 .{
486 .tag = .int_to_enum,
487 .param_count = 1,
488 },
486 },489 },
487 },
488 .{
489 "@intToError",
490 .{490 .{
491 .tag = .int_to_error,491 "@intToError",
492 .param_count = 1,492 .{
493 .tag = .int_to_error,
494 .param_count = 1,
495 },
493 },496 },
494 },
495 .{
496 "@intToFloat",
497 .{497 .{
498 .tag = .int_to_float,498 "@intToFloat",
499 .param_count = 1,499 .{
500 .tag = .int_to_float,
501 .param_count = 1,
502 },
500 },503 },
501 },
502 .{
503 "@intToPtr",
504 .{504 .{
505 .tag = .int_to_ptr,505 "@intToPtr",
506 .param_count = 2,506 .{
507 .tag = .int_to_ptr,
508 .param_count = 2,
509 },
507 },510 },
508 },
509 .{
510 "@memcpy",
511 .{511 .{
512 .tag = .memcpy,512 "@memcpy",
513 .param_count = 3,513 .{
514 .tag = .memcpy,
515 .param_count = 3,
516 },
514 },517 },
515 },
516 .{
517 "@memset",
518 .{518 .{
519 .tag = .memset,519 "@memset",
520 .param_count = 3,520 .{
521 .tag = .memset,
522 .param_count = 3,
523 },
521 },524 },
522 },
523 .{
524 "@wasmMemorySize",
525 .{525 .{
526 .tag = .wasm_memory_size,526 "@wasmMemorySize",
527 .param_count = 1,527 .{
528 .tag = .wasm_memory_size,
529 .param_count = 1,
530 },
528 },531 },
529 },
530 .{
531 "@wasmMemoryGrow",
532 .{532 .{
533 .tag = .wasm_memory_grow,533 "@wasmMemoryGrow",
534 .param_count = 2,534 .{
535 .tag = .wasm_memory_grow,
536 .param_count = 2,
537 },
535 },538 },
536 },
537 .{
538 "@mod",
539 .{539 .{
540 .tag = .mod,540 "@mod",
541 .param_count = 2,541 .{
542 .tag = .mod,
543 .param_count = 2,
544 },
542 },545 },
543 },
544 .{
545 "@mulWithOverflow",
546 .{546 .{
547 .tag = .mul_with_overflow,547 "@mulWithOverflow",
548 .param_count = 4,548 .{
549 .tag = .mul_with_overflow,
550 .param_count = 4,
551 },
549 },552 },
550 },
551 .{
552 "@panic",
553 .{553 .{
554 .tag = .panic,554 "@panic",
555 .param_count = 1,555 .{
556 .tag = .panic,
557 .param_count = 1,
558 },
556 },559 },
557 },
558 .{
559 "@popCount",
560 .{560 .{
561 .tag = .pop_count,561 "@popCount",
562 .param_count = 2,562 .{
563 .tag = .pop_count,
564 .param_count = 2,
565 },
563 },566 },
564 },
565 .{
566 "@ptrCast",
567 .{567 .{
568 .tag = .ptr_cast,568 "@ptrCast",
569 .param_count = 2,569 .{
570 .tag = .ptr_cast,
571 .param_count = 2,
572 },
570 },573 },
571 },
572 .{
573 "@ptrToInt",
574 .{574 .{
575 .tag = .ptr_to_int,575 "@ptrToInt",
576 .param_count = 1,576 .{
577 .tag = .ptr_to_int,
578 .param_count = 1,
579 },
577 },580 },
578 },
579 .{
580 "@rem",
581 .{581 .{
582 .tag = .rem,582 "@rem",
583 .param_count = 2,583 .{
584 .tag = .rem,
585 .param_count = 2,
586 },
584 },587 },
585 },
586 .{
587 "@returnAddress",
588 .{588 .{
589 .tag = .return_address,589 "@returnAddress",
590 .param_count = 0,590 .{
591 .tag = .return_address,
592 .param_count = 0,
593 },
591 },594 },
592 },
593 .{
594 "@setAlignStack",
595 .{595 .{
596 .tag = .set_align_stack,596 "@setAlignStack",
597 .param_count = 1,597 .{
598 .tag = .set_align_stack,
599 .param_count = 1,
600 },
598 },601 },
599 },
600 .{
601 "@setCold",
602 .{602 .{
603 .tag = .set_cold,603 "@setCold",
604 .param_count = 1,604 .{
605 .tag = .set_cold,
606 .param_count = 1,
607 },
605 },608 },
606 },
607 .{
608 "@setEvalBranchQuota",
609 .{609 .{
610 .tag = .set_eval_branch_quota,610 "@setEvalBranchQuota",
611 .param_count = 1,611 .{
612 .tag = .set_eval_branch_quota,
613 .param_count = 1,
614 },
612 },615 },
613 },
614 .{
615 "@setFloatMode",
616 .{616 .{
617 .tag = .set_float_mode,617 "@setFloatMode",
618 .param_count = 1,618 .{
619 .tag = .set_float_mode,
620 .param_count = 1,
621 },
619 },622 },
620 },
621 .{
622 "@setRuntimeSafety",
623 .{623 .{
624 .tag = .set_runtime_safety,624 "@setRuntimeSafety",
625 .param_count = 1,625 .{
626 .tag = .set_runtime_safety,
627 .param_count = 1,
628 },
626 },629 },
627 },
628 .{
629 "@shlExact",
630 .{630 .{
631 .tag = .shl_exact,631 "@shlExact",
632 .param_count = 2,632 .{
633 .tag = .shl_exact,
634 .param_count = 2,
635 },
633 },636 },
634 },
635 .{
636 "@shlWithOverflow",
637 .{637 .{
638 .tag = .shl_with_overflow,638 "@shlWithOverflow",
639 .param_count = 4,639 .{
640 .tag = .shl_with_overflow,
641 .param_count = 4,
642 },
640 },643 },
641 },
642 .{
643 "@shrExact",
644 .{644 .{
645 .tag = .shr_exact,645 "@shrExact",
646 .param_count = 2,646 .{
647 .tag = .shr_exact,
648 .param_count = 2,
649 },
647 },650 },
648 },
649 .{
650 "@shuffle",
651 .{651 .{
652 .tag = .shuffle,652 "@shuffle",
653 .param_count = 4,653 .{
654 .tag = .shuffle,
655 .param_count = 4,
656 },
654 },657 },
655 },
656 .{
657 "@sizeOf",
658 .{658 .{
659 .tag = .size_of,659 "@sizeOf",
660 .param_count = 1,660 .{
661 .tag = .size_of,
662 .param_count = 1,
663 },
661 },664 },
662 },
663 .{
664 "@splat",
665 .{665 .{
666 .tag = .splat,666 "@splat",
667 .needs_mem_loc = true,667 .{
668 .param_count = 2,668 .tag = .splat,
669 .needs_mem_loc = true,
670 .param_count = 2,
671 },
669 },672 },
670 },
671 .{
672 "@reduce",
673 .{673 .{
674 .tag = .reduce,674 "@reduce",
675 .param_count = 2,675 .{
676 .tag = .reduce,
677 .param_count = 2,
678 },
676 },679 },
677 },
678 .{
679 "@src",
680 .{680 .{
681 .tag = .src,681 "@src",
682 .needs_mem_loc = true,682 .{
683 .param_count = 0,683 .tag = .src,
684 .needs_mem_loc = true,
685 .param_count = 0,
686 },
684 },687 },
685 },
686 .{
687 "@sqrt",
688 .{688 .{
689 .tag = .sqrt,689 "@sqrt",
690 .param_count = 1,690 .{
691 .tag = .sqrt,
692 .param_count = 1,
693 },
691 },694 },
692 },
693 .{
694 "@sin",
695 .{695 .{
696 .tag = .sin,696 "@sin",
697 .param_count = 1,697 .{
698 .tag = .sin,
699 .param_count = 1,
700 },
698 },701 },
699 },
700 .{
701 "@cos",
702 .{702 .{
703 .tag = .cos,703 "@cos",
704 .param_count = 1,704 .{
705 .tag = .cos,
706 .param_count = 1,
707 },
705 },708 },
706 },
707 .{
708 "@exp",
709 .{709 .{
710 .tag = .exp,710 "@exp",
711 .param_count = 1,711 .{
712 .tag = .exp,
713 .param_count = 1,
714 },
712 },715 },
713 },
714 .{
715 "@exp2",
716 .{716 .{
717 .tag = .exp2,717 "@exp2",
718 .param_count = 1,718 .{
719 .tag = .exp2,
720 .param_count = 1,
721 },
719 },722 },
720 },
721 .{
722 "@log",
723 .{723 .{
724 .tag = .log,724 "@log",
725 .param_count = 1,725 .{
726 .tag = .log,
727 .param_count = 1,
728 },
726 },729 },
727 },
728 .{
729 "@log2",
730 .{730 .{
731 .tag = .log2,731 "@log2",
732 .param_count = 1,732 .{
733 .tag = .log2,
734 .param_count = 1,
735 },
733 },736 },
734 },
735 .{
736 "@log10",
737 .{737 .{
738 .tag = .log10,738 "@log10",
739 .param_count = 1,739 .{
740 .tag = .log10,
741 .param_count = 1,
742 },
740 },743 },
741 },
742 .{
743 "@fabs",
744 .{744 .{
745 .tag = .fabs,745 "@fabs",
746 .param_count = 1,746 .{
747 .tag = .fabs,
748 .param_count = 1,
749 },
747 },750 },
748 },
749 .{
750 "@floor",
751 .{751 .{
752 .tag = .floor,752 "@floor",
753 .param_count = 1,753 .{
754 .tag = .floor,
755 .param_count = 1,
756 },
754 },757 },
755 },
756 .{
757 "@ceil",
758 .{758 .{
759 .tag = .ceil,759 "@ceil",
760 .param_count = 1,760 .{
761 .tag = .ceil,
762 .param_count = 1,
763 },
761 },764 },
762 },
763 .{
764 "@trunc",
765 .{765 .{
766 .tag = .trunc,766 "@trunc",
767 .param_count = 1,767 .{
768 .tag = .trunc,
769 .param_count = 1,
770 },
768 },771 },
769 },
770 .{
771 "@round",
772 .{772 .{
773 .tag = .round,773 "@round",
774 .param_count = 1,774 .{
775 .tag = .round,
776 .param_count = 1,
777 },
775 },778 },
776 },
777 .{
778 "@subWithOverflow",
779 .{779 .{
780 .tag = .sub_with_overflow,780 "@subWithOverflow",
781 .param_count = 4,781 .{
782 .tag = .sub_with_overflow,
783 .param_count = 4,
784 },
782 },785 },
783 },
784 .{
785 "@tagName",
786 .{786 .{
787 .tag = .tag_name,787 "@tagName",
788 .param_count = 1,788 .{
789 .tag = .tag_name,
790 .param_count = 1,
791 },
789 },792 },
790 },
791 .{
792 "@This",
793 .{793 .{
794 .tag = .This,794 "@This",
795 .param_count = 0,795 .{
796 .tag = .This,
797 .param_count = 0,
798 },
796 },799 },
797 },
798 .{
799 "@truncate",
800 .{800 .{
801 .tag = .truncate,801 "@truncate",
802 .param_count = 2,802 .{
803 .tag = .truncate,
804 .param_count = 2,
805 },
803 },806 },
804 },
805 .{
806 "@Type",
807 .{807 .{
808 .tag = .Type,808 "@Type",
809 .param_count = 1,809 .{
810 .tag = .Type,
811 .param_count = 1,
812 },
810 },813 },
811 },
812 .{
813 "@typeInfo",
814 .{814 .{
815 .tag = .type_info,815 "@typeInfo",
816 .param_count = 1,816 .{
817 .tag = .type_info,
818 .param_count = 1,
819 },
817 },820 },
818 },
819 .{
820 "@typeName",
821 .{821 .{
822 .tag = .type_name,822 "@typeName",
823 .param_count = 1,823 .{
824 .tag = .type_name,
825 .param_count = 1,
826 },
824 },827 },
825 },
826 .{
827 "@TypeOf",
828 .{828 .{
829 .tag = .TypeOf,829 "@TypeOf",
830 .param_count = null,830 .{
831 .tag = .TypeOf,
832 .param_count = null,
833 },
831 },834 },
832 },
833 .{
834 "@unionInit",
835 .{835 .{
836 .tag = .union_init,836 "@unionInit",
837 .needs_mem_loc = true,837 .{
838 .param_count = 3,838 .tag = .union_init,
839 .needs_mem_loc = true,
840 .param_count = 3,
841 },
839 },842 },
840 },843 });
841});844};
src/Module.zig+9-8
...@@ -430,12 +430,12 @@ pub const Scope = struct {...@@ -430,12 +430,12 @@ pub const Scope = struct {
430 /// Asserts the scope is a child of a File and has an AST tree and returns the tree.430 /// Asserts the scope is a child of a File and has an AST tree and returns the tree.
431 pub fn tree(self: *Scope) *const ast.Tree {431 pub fn tree(self: *Scope) *const ast.Tree {
432 switch (self.tag) {432 switch (self.tag) {
433 .file => return self.cast(File).?.tree,433 .file => return &self.cast(File).?.tree,
434 .block => return self.cast(Block).?.src_decl.container.file_scope.tree,434 .block => return &self.cast(Block).?.src_decl.container.file_scope.tree,
435 .gen_zir => return self.cast(GenZIR).?.decl.container.file_scope.tree,435 .gen_zir => return &self.cast(GenZIR).?.decl.container.file_scope.tree,
436 .local_val => return self.cast(LocalVal).?.gen_zir.decl.container.file_scope.tree,436 .local_val => return &self.cast(LocalVal).?.gen_zir.decl.container.file_scope.tree,
437 .local_ptr => return self.cast(LocalPtr).?.gen_zir.decl.container.file_scope.tree,437 .local_ptr => return &self.cast(LocalPtr).?.gen_zir.decl.container.file_scope.tree,
438 .container => return self.cast(Container).?.file_scope.tree,438 .container => return &self.cast(Container).?.file_scope.tree,
439 }439 }
440 }440 }
441441
...@@ -1612,6 +1612,7 @@ fn astgenAndSemaVarDecl(...@@ -1612,6 +1612,7 @@ fn astgenAndSemaVarDecl(
1612 .decl = decl,1612 .decl = decl,
1613 .arena = &type_scope_arena.allocator,1613 .arena = &type_scope_arena.allocator,
1614 .parent = &decl.container.base,1614 .parent = &decl.container.base,
1615 .force_comptime = true,
1615 };1616 };
1616 defer type_scope.instructions.deinit(mod.gpa);1617 defer type_scope.instructions.deinit(mod.gpa);
16171618
...@@ -1630,7 +1631,7 @@ fn astgenAndSemaVarDecl(...@@ -1630,7 +1631,7 @@ fn astgenAndSemaVarDecl(
1630 } else {1631 } else {
1631 return mod.failTok(1632 return mod.failTok(
1632 &block_scope.base,1633 &block_scope.base,
1633 tree.firstToken(var_decl),1634 var_decl.ast.mut_token,
1634 "unable to infer variable type",1635 "unable to infer variable type",
1635 .{},1636 .{},
1636 );1637 );
...@@ -1639,7 +1640,7 @@ fn astgenAndSemaVarDecl(...@@ -1639,7 +1640,7 @@ fn astgenAndSemaVarDecl(
1639 if (is_mutable and !var_info.ty.isValidVarType(is_extern)) {1640 if (is_mutable and !var_info.ty.isValidVarType(is_extern)) {
1640 return mod.failTok(1641 return mod.failTok(
1641 &block_scope.base,1642 &block_scope.base,
1642 tree.firstToken(var_decl),1643 var_decl.ast.mut_token,
1643 "variable of type '{}' must be const",1644 "variable of type '{}' must be const",
1644 .{var_info.ty},1645 .{var_info.ty},
1645 );1646 );
src/astgen.zig+473-226
...@@ -59,6 +59,8 @@ pub const ResultLoc = union(enum) {...@@ -59,6 +59,8 @@ pub const ResultLoc = union(enum) {
5959
60pub fn typeExpr(mod: *Module, scope: *Scope, type_node: ast.Node.Index) InnerError!*zir.Inst {60pub fn typeExpr(mod: *Module, scope: *Scope, type_node: ast.Node.Index) InnerError!*zir.Inst {
61 const tree = scope.tree();61 const tree = scope.tree();
62 const token_starts = tree.tokens.items(.start);
63
62 const type_src = token_starts[tree.firstToken(type_node)];64 const type_src = token_starts[tree.firstToken(type_node)];
63 const type_type = try addZIRInstConst(mod, scope, type_src, .{65 const type_type = try addZIRInstConst(mod, scope, type_src, .{
64 .ty = Type.initTag(.type),66 .ty = Type.initTag(.type),
...@@ -76,13 +78,17 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.I...@@ -76,13 +78,17 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.I
76 .root => unreachable,78 .root => unreachable,
77 .@"usingnamespace" => unreachable,79 .@"usingnamespace" => unreachable,
78 .test_decl => unreachable,80 .test_decl => unreachable,
79 .doc_comment => unreachable,81 .global_var_decl => unreachable,
80 .var_decl => unreachable,82 .local_var_decl => unreachable,
83 .simple_var_decl => unreachable,
84 .aligned_var_decl => unreachable,
81 .switch_case => unreachable,85 .switch_case => unreachable,
82 .switch_else => unreachable,86 .switch_case_one => unreachable,
83 .container_field_init => unreachable,87 .container_field_init => unreachable,
84 .container_field_align => unreachable,88 .container_field_align => unreachable,
85 .container_field => unreachable,89 .container_field => unreachable,
90 .asm_output => unreachable,
91 .asm_input => unreachable,
8692
87 .assign,93 .assign,
88 .assign_bit_and,94 .assign_bit_and,
...@@ -122,58 +128,107 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.I...@@ -122,58 +128,107 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.I
122 .bool_and,128 .bool_and,
123 .bool_or,129 .bool_or,
124 .@"asm",130 .@"asm",
131 .asm_simple,
125 .string_literal,132 .string_literal,
126 .integer_literal,133 .integer_literal,
127 .call,134 .call,
128 .@"unreachable",135 .call_comma,
136 .async_call,
137 .async_call_comma,
138 .call_one,
139 .call_one_comma,
140 .async_call_one,
141 .async_call_one_comma,
142 .unreachable_literal,
129 .@"return",143 .@"return",
130 .@"if",144 .@"if",
145 .if_simple,
131 .@"while",146 .@"while",
147 .while_simple,
148 .while_cont,
132 .bool_not,149 .bool_not,
133 .address_of,150 .address_of,
134 .float_literal,151 .float_literal,
135 .undefined_literal,152 .undefined_literal,
136 .bool_literal,153 .true_literal,
154 .false_literal,
137 .null_literal,155 .null_literal,
138 .optional_type,156 .optional_type,
139 .block,157 .block,
140 .labeled_block,158 .block_semicolon,
159 .block_two,
160 .block_two_semicolon,
141 .@"break",161 .@"break",
142 .PtrType,162 .ptr_type_aligned,
163 .ptr_type_sentinel,
164 .ptr_type,
165 .ptr_type_bit_range,
143 .array_type,166 .array_type,
144 .array_type_sentinel,167 .array_type_sentinel,
145 .enum_literal,168 .enum_literal,
146 .MultilineStringLiteral,169 .multiline_string_literal,
147 .char_literal,170 .char_literal,
148 .@"defer",171 .@"defer",
172 .@"errdefer",
149 .@"catch",173 .@"catch",
150 .error_union,174 .error_union,
151 .merge_error_sets,175 .merge_error_sets,
152 .range,176 .switch_range,
153 .@"await",177 .@"await",
154 .bit_not,178 .bit_not,
155 .negation,179 .negation,
156 .negation_wrap,180 .negation_wrap,
157 .@"resume",181 .@"resume",
158 .@"try",182 .@"try",
159 .slice_type,
160 .slice,183 .slice,
161 .ArrayInitializer,184 .slice_open,
162 .ArrayInitializerDot,185 .slice_sentinel,
163 .StructInitializer,186 .array_init_one,
164 .StructInitializerDot,187 .array_init_one_comma,
188 .array_init_dot_two,
189 .array_init_dot_two_comma,
190 .array_init_dot,
191 .array_init_dot_comma,
192 .array_init,
193 .array_init_comma,
194 .struct_init_one,
195 .struct_init_one_comma,
196 .struct_init_dot_two,
197 .struct_init_dot_two_comma,
198 .struct_init_dot,
199 .struct_init_dot_comma,
200 .struct_init,
201 .struct_init_comma,
165 .@"switch",202 .@"switch",
203 .switch_comma,
166 .@"for",204 .@"for",
205 .for_simple,
167 .@"suspend",206 .@"suspend",
168 .@"continue",207 .@"continue",
169 .@"anytype",208 .@"anytype",
170 .error_type,209 .fn_proto_simple,
171 .FnProto,210 .fn_proto_multi,
211 .fn_proto_one,
212 .fn_proto,
213 .fn_decl,
172 .anyframe_type,214 .anyframe_type,
215 .anyframe_literal,
173 .error_set_decl,216 .error_set_decl,
174 .ContainerDecl,217 .container_decl,
218 .container_decl_comma,
219 .container_decl_two,
220 .container_decl_two_comma,
221 .container_decl_arg,
222 .container_decl_arg_comma,
223 .tagged_union,
224 .tagged_union_comma,
225 .tagged_union_two,
226 .tagged_union_two_comma,
227 .tagged_union_enum_tag,
228 .tagged_union_enum_tag_comma,
175 .@"comptime",229 .@"comptime",
176 .@"nosuspend",230 .@"nosuspend",
231 .error_value,
177 => return mod.failNode(scope, node, "invalid left-hand side to assignment", .{}),232 => return mod.failNode(scope, node, "invalid left-hand side to assignment", .{}),
178233
179 .builtin_call,234 .builtin_call,
...@@ -192,10 +247,10 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.I...@@ -192,10 +247,10 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.I
192 }247 }
193 },248 },
194249
195 // can be assigned to250 // These can be assigned to.
196 .unwrap_optional,251 .unwrap_optional,
197 .deref,252 .deref,
198 .period,253 .field_access,
199 .array_access,254 .array_access,
200 .identifier,255 .identifier,
201 .grouped_expression,256 .grouped_expression,
...@@ -210,22 +265,33 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.I...@@ -210,22 +265,33 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.I
210/// result instruction can be used to inspect whether it is isNoReturn() but that is it,265/// result instruction can be used to inspect whether it is isNoReturn() but that is it,
211/// it must otherwise not be used.266/// it must otherwise not be used.
212pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!*zir.Inst {267pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!*zir.Inst {
213 switch (node.tag) {268 const tree = scope.tree();
269 const main_tokens = tree.nodes.items(.main_token);
270 const token_tags = tree.tokens.items(.tag);
271 const node_datas = tree.nodes.items(.data);
272 const node_tags = tree.nodes.items(.tag);
273 const token_starts = tree.tokens.items(.start);
274
275 switch (node_tags[node]) {
214 .root => unreachable, // Top-level declaration.276 .root => unreachable, // Top-level declaration.
215 .@"usingnamespace" => unreachable, // Top-level declaration.277 .@"usingnamespace" => unreachable, // Top-level declaration.
216 .test_decl => unreachable, // Top-level declaration.278 .test_decl => unreachable, // Top-level declaration.
217 .doc_comment => unreachable, // Top-level declaration.279 .container_field_init => unreachable, // Top-level declaration.
218 .var_decl => unreachable, // Handled in `blockExpr`.280 .container_field_align => unreachable, // Top-level declaration.
281 .container_field => unreachable, // Top-level declaration.
282 .fn_decl => unreachable, // Top-level declaration.
283
284 .global_var_decl => unreachable, // Handled in `blockExpr`.
285 .local_var_decl => unreachable, // Handled in `blockExpr`.
286 .simple_var_decl => unreachable, // Handled in `blockExpr`.
287 .aligned_var_decl => unreachable, // Handled in `blockExpr`.
288
219 .switch_case => unreachable, // Handled in `switchExpr`.289 .switch_case => unreachable, // Handled in `switchExpr`.
220 .switch_else => unreachable, // Handled in `switchExpr`.290 .switch_case_one => unreachable, // Handled in `switchExpr`.
221 .range => unreachable, // Handled in `switchExpr`.291 .switch_range => unreachable, // Handled in `switchExpr`.
222 .Else => unreachable, // Handled explicitly the control flow expression functions.292
223 .Payload => unreachable, // Handled explicitly.293 .asm_output => unreachable, // Handled in `asmExpr`.
224 .PointerPayload => unreachable, // Handled explicitly.294 .asm_input => unreachable, // Handled in `asmExpr`.
225 .PointerIndexPayload => unreachable, // Handled explicitly.
226 .ErrorTag => unreachable, // Handled explicitly.
227 .FieldInitializer => unreachable, // Handled explicitly.
228 .ContainerField => unreachable, // Handled explicitly.
229295
230 .assign => return rvalueVoid(mod, scope, rl, node, try assign(mod, scope, node)),296 .assign => return rvalueVoid(mod, scope, rl, node, try assign(mod, scope, node)),
231 .assign_bit_and => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .bit_and)),297 .assign_bit_and => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .bit_and)),
...@@ -276,30 +342,28 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In...@@ -276,30 +342,28 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
276342
277 .identifier => return identifier(mod, scope, rl, node),343 .identifier => return identifier(mod, scope, rl, node),
278344
279 .asm_simple => return assembly(mod, scope, rl, tree.asmSimple(node)),345 .asm_simple => return asmExpr(mod, scope, rl, tree.asmSimple(node)),
280 .@"asm" => return assembly(mod, scope, rl, tree.asmFull(node)),346 .@"asm" => return asmExpr(mod, scope, rl, tree.asmFull(node)),
281347
282 .string_literal => return stringLiteral(mod, scope, rl, node),348 .string_literal => return stringLiteral(mod, scope, rl, node),
283 .multiline_string_literal => return multilineStringLiteral(mod, scope, rl, node),349 .multiline_string_literal => return multilineStringLiteral(mod, scope, rl, node),
284350
285 .integer_literal => return integerLiteral(mod, scope, rl, node),351 .integer_literal => return integerLiteral(mod, scope, rl, node),
286352
287 .builtin_call => return builtinCall(mod, scope, rl, node),
288
289 .builtin_call_two, .builtin_call_two_comma => {353 .builtin_call_two, .builtin_call_two_comma => {
290 if (datas[node].lhs == 0) {354 if (node_datas[node].lhs == 0) {
291 const params = [_]ast.Node.Index{};355 const params = [_]ast.Node.Index{};
292 return builtinCall(mod, scope, rl, node, &params);356 return builtinCall(mod, scope, rl, node, &params);
293 } else if (datas[node].rhs == 0) {357 } else if (node_datas[node].rhs == 0) {
294 const params = [_]ast.Node.Index{datas[node].lhs};358 const params = [_]ast.Node.Index{node_datas[node].lhs};
295 return builtinCall(mod, scope, rl, node, &params);359 return builtinCall(mod, scope, rl, node, &params);
296 } else {360 } else {
297 const params = [_]ast.Node.Index{ datas[node].lhs, datas[node].rhs };361 const params = [_]ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs };
298 return builtinCall(mod, scope, rl, node, &params);362 return builtinCall(mod, scope, rl, node, &params);
299 }363 }
300 },364 },
301 .builtin_call, .builtin_call_comma => {365 .builtin_call, .builtin_call_comma => {
302 const params = tree.extra_data[datas[node].lhs..datas[node].rhs];366 const params = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs];
303 return builtinCall(mod, scope, rl, node, params);367 return builtinCall(mod, scope, rl, node, params);
304 },368 },
305369
...@@ -311,20 +375,20 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In...@@ -311,20 +375,20 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
311 return callExpr(mod, scope, rl, tree.callFull(node));375 return callExpr(mod, scope, rl, tree.callFull(node));
312 },376 },
313377
314 .@"unreachable" => {378 .unreachable_literal => {
315 const main_token = main_tokens[node];379 const main_token = main_tokens[node];
316 const src = token_starts[main_token];380 const src = token_starts[main_token];
317 return addZIRNoOp(mod, scope, src, .unreachable_safe);381 return addZIRNoOp(mod, scope, src, .unreachable_safe);
318 },382 },
319 .@"return" => return ret(mod, scope, node),383 .@"return" => return ret(mod, scope, node),
320 .period => return field(mod, scope, rl, node),384 .field_access => return field(mod, scope, rl, node),
321 .float_literal => return floatLiteral(mod, scope, rl, node),385 .float_literal => return floatLiteral(mod, scope, rl, node),
322386
323 .if_simple => return ifExpr(mod, scope, rl, tree.ifSimple(node)),387 .if_simple => return ifExpr(mod, scope, rl, tree.ifSimple(node)),
324 .@"if" => return ifExpr(mode, scope, rl, tree.ifFull(node)),388 .@"if" => return ifExpr(mod, scope, rl, tree.ifFull(node)),
325389
326 .while_simple => return whileExpr(mod, scope, rl, tree.whileSimple(node)),390 .while_simple => return whileExpr(mod, scope, rl, tree.whileSimple(node)),
327 .while_cont => return whileExpr(mod, scope, tree.whileCont(node)),391 .while_cont => return whileExpr(mod, scope, rl, tree.whileCont(node)),
328 .@"while" => return whileExpr(mod, scope, rl, tree.whileFull(node)),392 .@"while" => return whileExpr(mod, scope, rl, tree.whileFull(node)),
329393
330 .for_simple => return forExpr(mod, scope, rl, tree.forSimple(node)),394 .for_simple => return forExpr(mod, scope, rl, tree.forSimple(node)),
...@@ -389,7 +453,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In...@@ -389,7 +453,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
389 return rvalue(mod, scope, rl, result);453 return rvalue(mod, scope, rl, result);
390 },454 },
391 .unwrap_optional => {455 .unwrap_optional => {
392 const operand = try expr(mod, scope, rl, node.lhs);456 const operand = try expr(mod, scope, rl, node_datas[node].lhs);
393 const op: zir.Inst.Tag = switch (rl) {457 const op: zir.Inst.Tag = switch (rl) {
394 .ref => .optional_payload_safe_ptr,458 .ref => .optional_payload_safe_ptr,
395 else => .optional_payload_safe,459 else => .optional_payload_safe,
...@@ -449,7 +513,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In...@@ -449,7 +513,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
449 },513 },
450 .@"catch" => {514 .@"catch" => {
451 const catch_token = main_tokens[node];515 const catch_token = main_tokens[node];
452 const payload_token: ?TokenIndex = if (token_tags[catch_token + 1] == .pipe)516 const payload_token: ?ast.TokenIndex = if (token_tags[catch_token + 1] == .pipe)
453 catch_token + 2517 catch_token + 2
454 else518 else
455 null;519 null;
...@@ -506,6 +570,34 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In...@@ -506,6 +570,34 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
506 null,570 null,
507 ),571 ),
508 },572 },
573
574 .ptr_type_aligned => return ptrType(mod, scope, rl, tree.ptrTypeAligned(node)),
575 .ptr_type_sentinel => return ptrType(mod, scope, rl, tree.ptrTypeSentinel(node)),
576 .ptr_type => return ptrType(mod, scope, rl, tree.ptrType(node)),
577 .ptr_type_bit_range => return ptrType(mod, scope, rl, tree.ptrTypeBitRange(node)),
578
579 .container_decl,
580 .container_decl_comma,
581 => return containerDecl(mod, scope, rl, tree.containerDecl(node)),
582 .container_decl_two, .container_decl_two_comma => {
583 var buffer: [2]ast.Node.Index = undefined;
584 return containerDecl(mod, scope, rl, tree.containerDeclTwo(&buffer, node));
585 },
586 .container_decl_arg,
587 .container_decl_arg_comma,
588 => return containerDecl(mod, scope, rl, tree.containerDeclArg(node)),
589
590 .tagged_union,
591 .tagged_union_comma,
592 => return containerDecl(mod, scope, rl, tree.taggedUnion(node)),
593 .tagged_union_two, .tagged_union_two_comma => {
594 var buffer: [2]ast.Node.Index = undefined;
595 return containerDecl(mod, scope, rl, tree.taggedUnionTwo(&buffer, node));
596 },
597 .tagged_union_enum_tag,
598 .tagged_union_enum_tag_comma,
599 => return containerDecl(mod, scope, rl, tree.taggedUnionEnumTag(node)),
600
509 .@"break" => return breakExpr(mod, scope, rl, node),601 .@"break" => return breakExpr(mod, scope, rl, node),
510 .@"continue" => return continueExpr(mod, scope, rl, node),602 .@"continue" => return continueExpr(mod, scope, rl, node),
511 .grouped_expression => return expr(mod, scope, rl, node_datas[node].lhs),603 .grouped_expression => return expr(mod, scope, rl, node_datas[node].lhs),
...@@ -518,12 +610,41 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In...@@ -518,12 +610,41 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
518 .@"switch", .switch_comma => return switchExpr(mod, scope, rl, node),610 .@"switch", .switch_comma => return switchExpr(mod, scope, rl, node),
519611
520 .@"defer" => return mod.failNode(scope, node, "TODO implement astgen.expr for .defer", .{}),612 .@"defer" => return mod.failNode(scope, node, "TODO implement astgen.expr for .defer", .{}),
613 .@"errdefer" => return mod.failNode(scope, node, "TODO implement astgen.expr for .errdefer", .{}),
521 .@"await" => return mod.failNode(scope, node, "TODO implement astgen.expr for .await", .{}),614 .@"await" => return mod.failNode(scope, node, "TODO implement astgen.expr for .await", .{}),
522 .@"resume" => return mod.failNode(scope, node, "TODO implement astgen.expr for .resume", .{}),615 .@"resume" => return mod.failNode(scope, node, "TODO implement astgen.expr for .resume", .{}),
523 .@"try" => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}),616 .@"try" => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}),
617
618 .array_init_one,
619 .array_init_one_comma,
620 .array_init_dot_two,
621 .array_init_dot_two_comma,
622 .array_init_dot,
623 .array_init_dot_comma,
624 .array_init,
625 .array_init_comma,
626 => return mod.failNode(scope, node, "TODO implement astgen.expr for array literals", .{}),
627
628 .struct_init_one,
629 .struct_init_one_comma,
630 .struct_init_dot_two,
631 .struct_init_dot_two_comma,
632 .struct_init_dot,
633 .struct_init_dot_comma,
634 .struct_init,
635 .struct_init_comma,
636 => return mod.failNode(scope, node, "TODO implement astgen.expr for struct literals", .{}),
637
524 .@"suspend" => return mod.failNode(scope, node, "TODO implement astgen.expr for .suspend", .{}),638 .@"suspend" => return mod.failNode(scope, node, "TODO implement astgen.expr for .suspend", .{}),
525 .@"anytype" => return mod.failNode(scope, node, "TODO implement astgen.expr for .anytype", .{}),639 .@"anytype" => return mod.failNode(scope, node, "TODO implement astgen.expr for .anytype", .{}),
640 .fn_proto_simple,
641 .fn_proto_multi,
642 .fn_proto_one,
643 .fn_proto,
644 => return mod.failNode(scope, node, "TODO implement astgen.expr for function prototypes", .{}),
645
526 .@"nosuspend" => return mod.failNode(scope, node, "TODO implement astgen.expr for .nosuspend", .{}),646 .@"nosuspend" => return mod.failNode(scope, node, "TODO implement astgen.expr for .nosuspend", .{}),
647 .error_value => return mod.failNode(scope, node, "TODO implement astgen.expr for .error_value", .{}),
527 }648 }
528}649}
529650
...@@ -572,6 +693,8 @@ fn breakExpr(...@@ -572,6 +693,8 @@ fn breakExpr(
572 const tree = parent_scope.tree();693 const tree = parent_scope.tree();
573 const node_datas = tree.nodes.items(.data);694 const node_datas = tree.nodes.items(.data);
574 const main_tokens = tree.nodes.items(.main_token);695 const main_tokens = tree.nodes.items(.main_token);
696 const token_starts = tree.tokens.items(.start);
697
575 const src = token_starts[main_tokens[node]];698 const src = token_starts[main_tokens[node]];
576 const break_label = node_datas[node].lhs;699 const break_label = node_datas[node].lhs;
577 const rhs = node_datas[node].rhs;700 const rhs = node_datas[node].rhs;
...@@ -646,6 +769,8 @@ fn continueExpr(...@@ -646,6 +769,8 @@ fn continueExpr(
646 const tree = parent_scope.tree();769 const tree = parent_scope.tree();
647 const node_datas = tree.nodes.items(.data);770 const node_datas = tree.nodes.items(.data);
648 const main_tokens = tree.nodes.items(.main_token);771 const main_tokens = tree.nodes.items(.main_token);
772 const token_starts = tree.tokens.items(.start);
773
649 const src = token_starts[main_tokens[node]];774 const src = token_starts[main_tokens[node]];
650 const break_label = node_datas[node].lhs;775 const break_label = node_datas[node].lhs;
651776
...@@ -702,7 +827,7 @@ pub fn blockExpr(...@@ -702,7 +827,7 @@ pub fn blockExpr(
702 const main_tokens = tree.nodes.items(.main_token);827 const main_tokens = tree.nodes.items(.main_token);
703 const token_tags = tree.tokens.items(.tag);828 const token_tags = tree.tokens.items(.tag);
704829
705 const lbrace = main_tokens[node];830 const lbrace = main_tokens[block_node];
706 if (token_tags[lbrace - 1] == .colon) {831 if (token_tags[lbrace - 1] == .colon) {
707 return labeledBlockExpr(mod, scope, rl, block_node, statements, .block);832 return labeledBlockExpr(mod, scope, rl, block_node, statements, .block);
708 }833 }
...@@ -721,8 +846,9 @@ fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIn...@@ -721,8 +846,9 @@ fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIn
721 if (gen_zir.label) |prev_label| {846 if (gen_zir.label) |prev_label| {
722 if (try tokenIdentEql(mod, parent_scope, label, prev_label.token)) {847 if (try tokenIdentEql(mod, parent_scope, label, prev_label.token)) {
723 const tree = parent_scope.tree();848 const tree = parent_scope.tree();
724 const node_datas = tree.nodes.items(.data);
725 const main_tokens = tree.nodes.items(.main_token);849 const main_tokens = tree.nodes.items(.main_token);
850 const token_starts = tree.tokens.items(.start);
851
726 const label_src = token_starts[label];852 const label_src = token_starts[label];
727 const prev_label_src = token_starts[prev_label.token];853 const prev_label_src = token_starts[prev_label.token];
728854
...@@ -770,9 +896,9 @@ fn labeledBlockExpr(...@@ -770,9 +896,9 @@ fn labeledBlockExpr(
770 assert(zir_tag == .block or zir_tag == .block_comptime);896 assert(zir_tag == .block or zir_tag == .block_comptime);
771897
772 const tree = parent_scope.tree();898 const tree = parent_scope.tree();
773 const node_datas = tree.nodes.items(.data);
774 const main_tokens = tree.nodes.items(.main_token);899 const main_tokens = tree.nodes.items(.main_token);
775 const token_starts = tree.tokens.items(.start);900 const token_starts = tree.tokens.items(.start);
901 const token_tags = tree.tokens.items(.tag);
776902
777 const lbrace = main_tokens[block_node];903 const lbrace = main_tokens[block_node];
778 const label_token = lbrace - 1;904 const label_token = lbrace - 1;
...@@ -813,10 +939,10 @@ fn labeledBlockExpr(...@@ -813,10 +939,10 @@ fn labeledBlockExpr(
813 defer block_scope.labeled_breaks.deinit(mod.gpa);939 defer block_scope.labeled_breaks.deinit(mod.gpa);
814 defer block_scope.labeled_store_to_block_ptr_list.deinit(mod.gpa);940 defer block_scope.labeled_store_to_block_ptr_list.deinit(mod.gpa);
815941
816 try blockExprStmts(mod, &block_scope.base, block_node, block_node.statements());942 try blockExprStmts(mod, &block_scope.base, block_node, statements);
817943
818 if (!block_scope.label.?.used) {944 if (!block_scope.label.?.used) {
819 return mod.fail(parent_scope, token_starts[block_node.label], "unused block label", .{});945 return mod.failTok(parent_scope, label_token, "unused block label", .{});
820 }946 }
821947
822 try gen_zir.instructions.append(mod.gpa, &block_inst.base);948 try gen_zir.instructions.append(mod.gpa, &block_inst.base);
...@@ -860,21 +986,23 @@ fn blockExprStmts(...@@ -860,21 +986,23 @@ fn blockExprStmts(
860 statements: []const ast.Node.Index,986 statements: []const ast.Node.Index,
861) !void {987) !void {
862 const tree = parent_scope.tree();988 const tree = parent_scope.tree();
863 const node_datas = tree.nodes.items(.data);
864 const main_tokens = tree.nodes.items(.main_token);989 const main_tokens = tree.nodes.items(.main_token);
990 const token_starts = tree.tokens.items(.start);
991 const node_tags = tree.nodes.items(.tag);
865992
866 var block_arena = std.heap.ArenaAllocator.init(mod.gpa);993 var block_arena = std.heap.ArenaAllocator.init(mod.gpa);
867 defer block_arena.deinit();994 defer block_arena.deinit();
868995
869 var scope = parent_scope;996 var scope = parent_scope;
870 for (statements) |statement| {997 for (statements) |statement| {
871 const src = token_starts[statement.firstToken()];998 const src = token_starts[tree.firstToken(statement)];
872 _ = try addZIRNoOp(mod, scope, src, .dbg_stmt);999 _ = try addZIRNoOp(mod, scope, src, .dbg_stmt);
873 switch (statement.tag) {1000 switch (node_tags[statement]) {
874 .var_decl => {1001 .global_var_decl => scope = try varDecl(mod, scope, &block_arena.allocator, tree.globalVarDecl(statement)),
875 const var_decl_node = statement.castTag(.var_decl).?;1002 .local_var_decl => scope = try varDecl(mod, scope, &block_arena.allocator, tree.localVarDecl(statement)),
876 scope = try varDecl(mod, scope, var_decl_node, &block_arena.allocator);1003 .simple_var_decl => scope = try varDecl(mod, scope, &block_arena.allocator, tree.simpleVarDecl(statement)),
877 },1004 .aligned_var_decl => scope = try varDecl(mod, scope, &block_arena.allocator, tree.alignedVarDecl(statement)),
1005
878 .assign => try assign(mod, scope, statement),1006 .assign => try assign(mod, scope, statement),
879 .assign_bit_and => try assignOp(mod, scope, statement, .bit_and),1007 .assign_bit_and => try assignOp(mod, scope, statement, .bit_and),
880 .assign_bit_or => try assignOp(mod, scope, statement, .bit_or),1008 .assign_bit_or => try assignOp(mod, scope, statement, .bit_or),
...@@ -903,20 +1031,23 @@ fn blockExprStmts(...@@ -903,20 +1031,23 @@ fn blockExprStmts(
903fn varDecl(1031fn varDecl(
904 mod: *Module,1032 mod: *Module,
905 scope: *Scope,1033 scope: *Scope,
906 node: *ast.Node.var_decl,
907 block_arena: *Allocator,1034 block_arena: *Allocator,
1035 var_decl: ast.full.VarDecl,
908) InnerError!*Scope {1036) InnerError!*Scope {
909 if (node.getComptimeToken()) |comptime_token| {1037 if (var_decl.comptime_token) |comptime_token| {
910 return mod.failTok(scope, comptime_token, "TODO implement comptime locals", .{});1038 return mod.failTok(scope, comptime_token, "TODO implement comptime locals", .{});
911 }1039 }
912 if (node.getAlignNode()) |align_node| {1040 if (var_decl.ast.align_node != 0) {
913 return mod.failNode(scope, align_node, "TODO implement alignment on locals", .{});1041 return mod.failNode(scope, var_decl.ast.align_node, "TODO implement alignment on locals", .{});
914 }1042 }
915 const tree = scope.tree();1043 const tree = scope.tree();
916 const node_datas = tree.nodes.items(.data);
917 const main_tokens = tree.nodes.items(.main_token);1044 const main_tokens = tree.nodes.items(.main_token);
918 const name_src = token_starts[node.name_token];1045 const token_starts = tree.tokens.items(.start);
919 const ident_name = try mod.identifierTokenString(scope, node.name_token);1046 const token_tags = tree.tokens.items(.tag);
1047
1048 const name_token = var_decl.ast.mut_token + 1;
1049 const name_src = token_starts[name_token];
1050 const ident_name = try mod.identifierTokenString(scope, name_token);
9201051
921 // Local variables shadowing detection, including function parameters.1052 // Local variables shadowing detection, including function parameters.
922 {1053 {
...@@ -962,20 +1093,21 @@ fn varDecl(...@@ -962,20 +1093,21 @@ fn varDecl(
962 // TODO add note for other definition1093 // TODO add note for other definition
963 return mod.fail(scope, name_src, "redefinition of '{s}'", .{ident_name});1094 return mod.fail(scope, name_src, "redefinition of '{s}'", .{ident_name});
964 }1095 }
965 const init_node = node.getInitNode() orelse1096 if (var_decl.ast.init_node == 0) {
966 return mod.fail(scope, name_src, "variables must be initialized", .{});1097 return mod.fail(scope, name_src, "variables must be initialized", .{});
1098 }
9671099
968 switch (tree.token_ids[node.mut_token]) {1100 switch (token_tags[var_decl.ast.mut_token]) {
969 .keyword_const => {1101 .keyword_const => {
970 // Depending on the type of AST the initialization expression is, we may need an lvalue1102 // Depending on the type of AST the initialization expression is, we may need an lvalue
971 // or an rvalue as a result location. If it is an rvalue, we can use the instruction as1103 // or an rvalue as a result location. If it is an rvalue, we can use the instruction as
972 // the variable, no memory location needed.1104 // the variable, no memory location needed.
973 if (!nodeMayNeedMemoryLocation(init_node, scope)) {1105 if (!nodeMayNeedMemoryLocation(scope, var_decl.ast.init_node)) {
974 const result_loc: ResultLoc = if (node.getTypeNode()) |type_node|1106 const result_loc: ResultLoc = if (var_decl.ast.type_node != 0)
975 .{ .ty = try typeExpr(mod, scope, type_node) }1107 .{ .ty = try typeExpr(mod, scope, var_decl.ast.type_node) }
976 else1108 else
977 .none;1109 .none;
978 const init_inst = try expr(mod, scope, result_loc, init_node);1110 const init_inst = try expr(mod, scope, result_loc, var_decl.ast.init_node);
979 const sub_scope = try block_arena.create(Scope.LocalVal);1111 const sub_scope = try block_arena.create(Scope.LocalVal);
980 sub_scope.* = .{1112 sub_scope.* = .{
981 .parent = scope,1113 .parent = scope,
...@@ -999,8 +1131,8 @@ fn varDecl(...@@ -999,8 +1131,8 @@ fn varDecl(
9991131
1000 var resolve_inferred_alloc: ?*zir.Inst = null;1132 var resolve_inferred_alloc: ?*zir.Inst = null;
1001 var opt_type_inst: ?*zir.Inst = null;1133 var opt_type_inst: ?*zir.Inst = null;
1002 if (node.getTypeNode()) |type_node| {1134 if (var_decl.ast.type_node != 0) {
1003 const type_inst = try typeExpr(mod, &init_scope.base, type_node);1135 const type_inst = try typeExpr(mod, &init_scope.base, var_decl.ast.type_node);
1004 opt_type_inst = type_inst;1136 opt_type_inst = type_inst;
1005 init_scope.rl_ptr = try addZIRUnOp(mod, &init_scope.base, name_src, .alloc, type_inst);1137 init_scope.rl_ptr = try addZIRUnOp(mod, &init_scope.base, name_src, .alloc, type_inst);
1006 } else {1138 } else {
...@@ -1009,7 +1141,7 @@ fn varDecl(...@@ -1009,7 +1141,7 @@ fn varDecl(
1009 init_scope.rl_ptr = &alloc.base;1141 init_scope.rl_ptr = &alloc.base;
1010 }1142 }
1011 const init_result_loc: ResultLoc = .{ .block_ptr = &init_scope };1143 const init_result_loc: ResultLoc = .{ .block_ptr = &init_scope };
1012 const init_inst = try expr(mod, &init_scope.base, init_result_loc, init_node);1144 const init_inst = try expr(mod, &init_scope.base, init_result_loc, var_decl.ast.init_node);
1013 const parent_zir = &scope.getGenZIR().instructions;1145 const parent_zir = &scope.getGenZIR().instructions;
1014 if (init_scope.rvalue_rl_count == 1) {1146 if (init_scope.rvalue_rl_count == 1) {
1015 // Result location pointer not used. We don't need an alloc for this1147 // Result location pointer not used. We don't need an alloc for this
...@@ -1069,8 +1201,11 @@ fn varDecl(...@@ -1069,8 +1201,11 @@ fn varDecl(
1069 },1201 },
1070 .keyword_var => {1202 .keyword_var => {
1071 var resolve_inferred_alloc: ?*zir.Inst = null;1203 var resolve_inferred_alloc: ?*zir.Inst = null;
1072 const var_data: struct { result_loc: ResultLoc, alloc: *zir.Inst } = if (node.getTypeNode()) |type_node| a: {1204 const var_data: struct {
1073 const type_inst = try typeExpr(mod, scope, type_node);1205 result_loc: ResultLoc,
1206 alloc: *zir.Inst,
1207 } = if (var_decl.ast.type_node != 0) a: {
1208 const type_inst = try typeExpr(mod, scope, var_decl.ast.type_node);
1074 const alloc = try addZIRUnOp(mod, scope, name_src, .alloc_mut, type_inst);1209 const alloc = try addZIRUnOp(mod, scope, name_src, .alloc_mut, type_inst);
1075 break :a .{ .alloc = alloc, .result_loc = .{ .ptr = alloc } };1210 break :a .{ .alloc = alloc, .result_loc = .{ .ptr = alloc } };
1076 } else a: {1211 } else a: {
...@@ -1078,7 +1213,7 @@ fn varDecl(...@@ -1078,7 +1213,7 @@ fn varDecl(
1078 resolve_inferred_alloc = &alloc.base;1213 resolve_inferred_alloc = &alloc.base;
1079 break :a .{ .alloc = &alloc.base, .result_loc = .{ .inferred_ptr = alloc } };1214 break :a .{ .alloc = &alloc.base, .result_loc = .{ .inferred_ptr = alloc } };
1080 };1215 };
1081 const init_inst = try expr(mod, scope, var_data.result_loc, init_node);1216 const init_inst = try expr(mod, scope, var_data.result_loc, var_decl.ast.init_node);
1082 if (resolve_inferred_alloc) |inst| {1217 if (resolve_inferred_alloc) |inst| {
1083 _ = try addZIRUnOp(mod, scope, name_src, .resolve_inferred_alloc, inst);1218 _ = try addZIRUnOp(mod, scope, name_src, .resolve_inferred_alloc, inst);
1084 }1219 }
...@@ -1099,13 +1234,15 @@ fn assign(mod: *Module, scope: *Scope, infix_node: ast.Node.Index) InnerError!vo...@@ -1099,13 +1234,15 @@ fn assign(mod: *Module, scope: *Scope, infix_node: ast.Node.Index) InnerError!vo
1099 const tree = scope.tree();1234 const tree = scope.tree();
1100 const node_datas = tree.nodes.items(.data);1235 const node_datas = tree.nodes.items(.data);
1101 const main_tokens = tree.nodes.items(.main_token);1236 const main_tokens = tree.nodes.items(.main_token);
1237 const node_tags = tree.nodes.items(.tag);
1238
1102 const lhs = node_datas[infix_node].lhs;1239 const lhs = node_datas[infix_node].lhs;
1103 const rhs = node_datas[infix_node].rhs;1240 const rhs = node_datas[infix_node].rhs;
1104 if (node_tags[lhs] == .identifier) {1241 if (node_tags[lhs] == .identifier) {
1105 // This intentionally does not support `@"_"` syntax.1242 // This intentionally does not support `@"_"` syntax.
1106 const ident_name = tree.tokenSlice(main_tokens[lhs]);1243 const ident_name = tree.tokenSlice(main_tokens[lhs]);
1107 if (mem.eql(u8, ident_name, "_")) {1244 if (mem.eql(u8, ident_name, "_")) {
1108 _ = try expr(mod, scope, .discard, infix_node.rhs);1245 _ = try expr(mod, scope, .discard, rhs);
1109 return;1246 return;
1110 }1247 }
1111 }1248 }
...@@ -1122,6 +1259,7 @@ fn assignOp(...@@ -1122,6 +1259,7 @@ fn assignOp(
1122 const tree = scope.tree();1259 const tree = scope.tree();
1123 const node_datas = tree.nodes.items(.data);1260 const node_datas = tree.nodes.items(.data);
1124 const main_tokens = tree.nodes.items(.main_token);1261 const main_tokens = tree.nodes.items(.main_token);
1262 const token_starts = tree.tokens.items(.start);
11251263
1126 const lhs_ptr = try lvalExpr(mod, scope, node_datas[infix_node].lhs);1264 const lhs_ptr = try lvalExpr(mod, scope, node_datas[infix_node].lhs);
1127 const lhs = try addZIRUnOp(mod, scope, lhs_ptr.src, .deref, lhs_ptr);1265 const lhs = try addZIRUnOp(mod, scope, lhs_ptr.src, .deref, lhs_ptr);
...@@ -1136,6 +1274,7 @@ fn boolNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.In...@@ -1136,6 +1274,7 @@ fn boolNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.In
1136 const tree = scope.tree();1274 const tree = scope.tree();
1137 const node_datas = tree.nodes.items(.data);1275 const node_datas = tree.nodes.items(.data);
1138 const main_tokens = tree.nodes.items(.main_token);1276 const main_tokens = tree.nodes.items(.main_token);
1277 const token_starts = tree.tokens.items(.start);
11391278
1140 const src = token_starts[main_tokens[node]];1279 const src = token_starts[main_tokens[node]];
1141 const bool_type = try addZIRInstConst(mod, scope, src, .{1280 const bool_type = try addZIRInstConst(mod, scope, src, .{
...@@ -1150,6 +1289,7 @@ fn bitNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Ins...@@ -1150,6 +1289,7 @@ fn bitNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Ins
1150 const tree = scope.tree();1289 const tree = scope.tree();
1151 const node_datas = tree.nodes.items(.data);1290 const node_datas = tree.nodes.items(.data);
1152 const main_tokens = tree.nodes.items(.main_token);1291 const main_tokens = tree.nodes.items(.main_token);
1292 const token_starts = tree.tokens.items(.start);
11531293
1154 const src = token_starts[main_tokens[node]];1294 const src = token_starts[main_tokens[node]];
1155 const operand = try expr(mod, scope, .none, node_datas[node].lhs);1295 const operand = try expr(mod, scope, .none, node_datas[node].lhs);
...@@ -1165,6 +1305,7 @@ fn negation(...@@ -1165,6 +1305,7 @@ fn negation(
1165 const tree = scope.tree();1305 const tree = scope.tree();
1166 const node_datas = tree.nodes.items(.data);1306 const node_datas = tree.nodes.items(.data);
1167 const main_tokens = tree.nodes.items(.main_token);1307 const main_tokens = tree.nodes.items(.main_token);
1308 const token_starts = tree.tokens.items(.start);
11681309
1169 const src = token_starts[main_tokens[node]];1310 const src = token_starts[main_tokens[node]];
1170 const lhs = try addZIRInstConst(mod, scope, src, .{1311 const lhs = try addZIRInstConst(mod, scope, src, .{
...@@ -1175,53 +1316,61 @@ fn negation(...@@ -1175,53 +1316,61 @@ fn negation(
1175 return addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs);1316 return addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs);
1176}1317}
11771318
1178fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo, rhs: *ast.Node, size: std.builtin.TypeInfo.Pointer.Size) InnerError!*zir.Inst {1319fn ptrType(
1320 mod: *Module,
1321 scope: *Scope,
1322 rl: ResultLoc,
1323 ptr_info: ast.full.PtrType,
1324) InnerError!*zir.Inst {
1325 const tree = scope.tree();
1326 const token_starts = tree.tokens.items(.start);
1327
1328 const src = token_starts[ptr_info.ast.main_token];
1329
1179 const simple = ptr_info.allowzero_token == null and1330 const simple = ptr_info.allowzero_token == null and
1180 ptr_info.align_info == null and1331 ptr_info.ast.align_node == 0 and
1181 ptr_info.volatile_token == null and1332 ptr_info.volatile_token == null and
1182 ptr_info.sentinel == null;1333 ptr_info.ast.sentinel == 0;
11831334
1184 if (simple) {1335 if (simple) {
1185 const child_type = try typeExpr(mod, scope, rhs);1336 const child_type = try typeExpr(mod, scope, ptr_info.ast.child_type);
1186 const mutable = ptr_info.const_token == null;1337 const mutable = ptr_info.const_token == null;
1187 // TODO stage1 type inference bug
1188 const T = zir.Inst.Tag;1338 const T = zir.Inst.Tag;
1189 return addZIRUnOp(mod, scope, src, switch (size) {1339 const result = try addZIRUnOp(mod, scope, src, switch (ptr_info.size) {
1190 .One => if (mutable) T.single_mut_ptr_type else T.single_const_ptr_type,1340 .One => if (mutable) T.single_mut_ptr_type else T.single_const_ptr_type,
1191 .Many => if (mutable) T.many_mut_ptr_type else T.many_const_ptr_type,1341 .Many => if (mutable) T.many_mut_ptr_type else T.many_const_ptr_type,
1192 .C => if (mutable) T.c_mut_ptr_type else T.c_const_ptr_type,1342 .C => if (mutable) T.c_mut_ptr_type else T.c_const_ptr_type,
1193 .Slice => if (mutable) T.mut_slice_type else T.const_slice_type,1343 .Slice => if (mutable) T.mut_slice_type else T.const_slice_type,
1194 }, child_type);1344 }, child_type);
1345 return rvalue(mod, scope, rl, result);
1195 }1346 }
11961347
1197 var kw_args: std.meta.fieldInfo(zir.Inst.PtrType, .kw_args).field_type = .{};1348 var kw_args: std.meta.fieldInfo(zir.Inst.PtrType, .kw_args).field_type = .{};
1198 kw_args.size = size;1349 kw_args.size = ptr_info.size;
1199 kw_args.@"allowzero" = ptr_info.allowzero_token != null;1350 kw_args.@"allowzero" = ptr_info.allowzero_token != null;
1200 if (ptr_info.align_info) |some| {1351 if (ptr_info.ast.align_node != 0) {
1201 kw_args.@"align" = try expr(mod, scope, .none, some.node);1352 kw_args.@"align" = try expr(mod, scope, .none, ptr_info.ast.align_node);
1202 if (some.bit_range) |bit_range| {1353 if (ptr_info.ast.bit_range_start != 0) {
1203 kw_args.align_bit_start = try expr(mod, scope, .none, bit_range.start);1354 kw_args.align_bit_start = try expr(mod, scope, .none, ptr_info.ast.bit_range_start);
1204 kw_args.align_bit_end = try expr(mod, scope, .none, bit_range.end);1355 kw_args.align_bit_end = try expr(mod, scope, .none, ptr_info.ast.bit_range_end);
1205 }1356 }
1206 }1357 }
1207 kw_args.mutable = ptr_info.const_token == null;1358 kw_args.mutable = ptr_info.const_token == null;
1208 kw_args.@"volatile" = ptr_info.volatile_token != null;1359 kw_args.@"volatile" = ptr_info.volatile_token != null;
1209 if (ptr_info.sentinel) |some| {1360 const child_type = try typeExpr(mod, scope, ptr_info.ast.child_type);
1210 kw_args.sentinel = try expr(mod, scope, .none, some);1361 if (ptr_info.ast.sentinel != 0) {
1211 }1362 kw_args.sentinel = try expr(mod, scope, .{ .ty = child_type }, ptr_info.ast.sentinel);
1212
1213 const child_type = try typeExpr(mod, scope, rhs);
1214 if (kw_args.sentinel) |some| {
1215 kw_args.sentinel = try addZIRBinOp(mod, scope, some.src, .as, child_type, some);
1216 }1363 }
12171364 const result = try addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args);
1218 return addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args);1365 return rvalue(mod, scope, rl, result);
1219}1366}
12201367
1221fn arrayType(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !*zir.Inst {1368fn arrayType(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !*zir.Inst {
1222 const tree = scope.tree();1369 const tree = scope.tree();
1223 const main_tokens = tree.nodes.items(.main_token);1370 const main_tokens = tree.nodes.items(.main_token);
1224 const node_datas = tree.nodes.items(.data);1371 const node_datas = tree.nodes.items(.data);
1372 const token_starts = tree.tokens.items(.start);
1373
1225 const src = token_starts[main_tokens[node]];1374 const src = token_starts[main_tokens[node]];
1226 const usize_type = try addZIRInstConst(mod, scope, src, .{1375 const usize_type = try addZIRInstConst(mod, scope, src, .{
1227 .ty = Type.initTag(.type),1376 .ty = Type.initTag(.type),
...@@ -1246,6 +1395,9 @@ fn arrayType(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !...@@ -1246,6 +1395,9 @@ fn arrayType(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !
1246fn arrayTypeSentinel(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !*zir.Inst {1395fn arrayTypeSentinel(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !*zir.Inst {
1247 const tree = scope.tree();1396 const tree = scope.tree();
1248 const main_tokens = tree.nodes.items(.main_token);1397 const main_tokens = tree.nodes.items(.main_token);
1398 const token_starts = tree.tokens.items(.start);
1399 const node_datas = tree.nodes.items(.data);
1400
1249 const len_node = node_datas[node].lhs;1401 const len_node = node_datas[node].lhs;
1250 const extra = tree.extraData(node_datas[node].rhs, ast.Node.ArrayTypeSentinel);1402 const extra = tree.extraData(node_datas[node].rhs, ast.Node.ArrayTypeSentinel);
1251 const src = token_starts[main_tokens[node]];1403 const src = token_starts[main_tokens[node]];
...@@ -1274,6 +1426,8 @@ fn containerField(...@@ -1274,6 +1426,8 @@ fn containerField(
1274 node: *ast.Node.ContainerField,1426 node: *ast.Node.ContainerField,
1275) InnerError!*zir.Inst {1427) InnerError!*zir.Inst {
1276 const tree = scope.tree();1428 const tree = scope.tree();
1429 const token_starts = tree.tokens.items(.start);
1430
1277 const src = token_starts[tree.firstToken(node)];1431 const src = token_starts[tree.firstToken(node)];
1278 const name = try mod.identifierTokenString(scope, node.name_token);1432 const name = try mod.identifierTokenString(scope, node.name_token);
12791433
...@@ -1305,9 +1459,18 @@ fn containerField(...@@ -1305,9 +1459,18 @@ fn containerField(
1305 });1459 });
1306}1460}
13071461
1308fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.ContainerDecl) InnerError!*zir.Inst {1462fn containerDecl(
1463 mod: *Module,
1464 scope: *Scope,
1465 rl: ResultLoc,
1466 container_decl: ast.full.ContainerDecl,
1467) InnerError!*zir.Inst {
1309 const tree = scope.tree();1468 const tree = scope.tree();
1310 const src = token_starts[node.kind_token];1469 const token_starts = tree.tokens.items(.start);
1470 const node_tags = tree.nodes.items(.tag);
1471 const token_tags = tree.tokens.items(.tag);
1472
1473 const src = token_starts[container_decl.ast.main_token];
13111474
1312 var gen_scope: Scope.GenZIR = .{1475 var gen_scope: Scope.GenZIR = .{
1313 .parent = scope,1476 .parent = scope,
...@@ -1321,9 +1484,12 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con...@@ -1321,9 +1484,12 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
1321 var fields = std.ArrayList(*zir.Inst).init(mod.gpa);1484 var fields = std.ArrayList(*zir.Inst).init(mod.gpa);
1322 defer fields.deinit();1485 defer fields.deinit();
13231486
1324 for (node.fieldsAndDecls()) |fd| {1487 for (container_decl.ast.members) |member| {
1325 if (fd.castTag(.ContainerField)) |f| {1488 switch (node_tags[member]) {
1326 try fields.append(try containerField(mod, &gen_scope.base, f));1489 .container_field_init, .container_field_align, .container_field => {
1490 try fields.append(try containerField(mod, &gen_scope.base, member));
1491 },
1492 else => continue,
1327 }1493 }
1328 }1494 }
13291495
...@@ -1332,19 +1498,22 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con...@@ -1332,19 +1498,22 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
1332 const arena = &decl_arena.allocator;1498 const arena = &decl_arena.allocator;
13331499
1334 var layout: std.builtin.TypeInfo.ContainerLayout = .Auto;1500 var layout: std.builtin.TypeInfo.ContainerLayout = .Auto;
1335 if (node.layout_token) |some| switch (tree.token_ids[some]) {1501 if (container_decl.layout_token) |some| switch (token_tags[some]) {
1336 .keyword_extern => layout = .Extern,1502 .keyword_extern => layout = .Extern,
1337 .keyword_packed => layout = .Packed,1503 .keyword_packed => layout = .Packed,
1338 else => unreachable,1504 else => unreachable,
1339 };1505 };
13401506
1341 const container_type = switch (tree.token_ids[node.kind_token]) {1507 // TODO this implementation is incorrect. The types must be created in semantic
1508 // analysis, not astgen, because the same ZIR is re-used for multiple inline function calls,
1509 // comptime function calls, and generic function instantiations, and these
1510 // must result in different instances of container types.
1511 const container_type = switch (token_tags[container_decl.ast.main_token]) {
1342 .keyword_enum => blk: {1512 .keyword_enum => blk: {
1343 const tag_type: ?*zir.Inst = switch (node.init_arg_expr) {1513 const tag_type: ?*zir.Inst = if (container_decl.ast.arg != 0)
1344 .Type => |t| try typeExpr(mod, &gen_scope.base, t),1514 try typeExpr(mod, &gen_scope.base, container_decl.ast.arg)
1345 .None => null,1515 else
1346 .Enum => unreachable,1516 null;
1347 };
1348 const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.EnumType, .{1517 const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.EnumType, .{
1349 .fields = try arena.dupe(*zir.Inst, fields.items),1518 .fields = try arena.dupe(*zir.Inst, fields.items),
1350 }, .{1519 }, .{
...@@ -1367,7 +1536,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con...@@ -1367,7 +1536,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
1367 break :blk Type.initPayload(&enum_type.base);1536 break :blk Type.initPayload(&enum_type.base);
1368 },1537 },
1369 .keyword_struct => blk: {1538 .keyword_struct => blk: {
1370 assert(node.init_arg_expr == .None);1539 assert(container_decl.ast.arg == 0);
1371 const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.StructType, .{1540 const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.StructType, .{
1372 .fields = try arena.dupe(*zir.Inst, fields.items),1541 .fields = try arena.dupe(*zir.Inst, fields.items),
1373 }, .{1542 }, .{
...@@ -1389,21 +1558,16 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con...@@ -1389,21 +1558,16 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
1389 break :blk Type.initPayload(&struct_type.base);1558 break :blk Type.initPayload(&struct_type.base);
1390 },1559 },
1391 .keyword_union => blk: {1560 .keyword_union => blk: {
1392 const init_inst = switch (node.init_arg_expr) {1561 const init_inst: ?*zir.Inst = if (container_decl.ast.arg != 0)
1393 .Enum => |e| if (e) |t| try typeExpr(mod, &gen_scope.base, t) else null,1562 try typeExpr(mod, &gen_scope.base, container_decl.ast.arg)
1394 .None => null,1563 else
1395 .Type => |t| try typeExpr(mod, &gen_scope.base, t),1564 null;
1396 };1565 const has_enum_token = container_decl.ast.enum_token != null;
1397 const init_kind: zir.Inst.UnionType.InitKind = switch (node.init_arg_expr) {
1398 .Enum => .enum_type,
1399 .None => .none,
1400 .Type => .tag_type,
1401 };
1402 const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.UnionType, .{1566 const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.UnionType, .{
1403 .fields = try arena.dupe(*zir.Inst, fields.items),1567 .fields = try arena.dupe(*zir.Inst, fields.items),
1404 }, .{1568 }, .{
1405 .layout = layout,1569 .layout = layout,
1406 .init_kind = init_kind,1570 .has_enum_token = has_enum_token,
1407 .init_inst = init_inst,1571 .init_inst = init_inst,
1408 });1572 });
1409 const union_type = try arena.create(Type.Payload.Union);1573 const union_type = try arena.create(Type.Payload.Union);
...@@ -1437,7 +1601,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con...@@ -1437,7 +1601,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
1437 else => unreachable,1601 else => unreachable,
1438 };1602 };
1439 const val = try Value.Tag.ty.create(arena, container_type);1603 const val = try Value.Tag.ty.create(arena, container_type);
1440 const decl = try mod.createContainerDecl(scope, node.kind_token, &decl_arena, .{1604 const decl = try mod.createContainerDecl(scope, container_decl.ast.main_token, &decl_arena, .{
1441 .ty = Type.initTag(.type),1605 .ty = Type.initTag(.type),
1442 .val = val,1606 .val = val,
1443 });1607 });
...@@ -1459,6 +1623,7 @@ fn errorSetDecl(...@@ -1459,6 +1623,7 @@ fn errorSetDecl(
1459 const tree = scope.tree();1623 const tree = scope.tree();
1460 const main_tokens = tree.nodes.items(.main_token);1624 const main_tokens = tree.nodes.items(.main_token);
1461 const token_tags = tree.tokens.items(.tag);1625 const token_tags = tree.tokens.items(.tag);
1626 const token_starts = tree.tokens.items(.start);
14621627
1463 // Count how many fields there are.1628 // Count how many fields there are.
1464 const error_token = main_tokens[node];1629 const error_token = main_tokens[node];
...@@ -1500,15 +1665,17 @@ fn orelseCatchExpr(...@@ -1500,15 +1665,17 @@ fn orelseCatchExpr(
1500 mod: *Module,1665 mod: *Module,
1501 scope: *Scope,1666 scope: *Scope,
1502 rl: ResultLoc,1667 rl: ResultLoc,
1503 lhs: *ast.Node,1668 lhs: ast.Node.Index,
1504 op_token: ast.TokenIndex,1669 op_token: ast.TokenIndex,
1505 cond_op: zir.Inst.Tag,1670 cond_op: zir.Inst.Tag,
1506 unwrap_op: zir.Inst.Tag,1671 unwrap_op: zir.Inst.Tag,
1507 unwrap_code_op: zir.Inst.Tag,1672 unwrap_code_op: zir.Inst.Tag,
1508 rhs: *ast.Node,1673 rhs: ast.Node.Index,
1509 payload_node: ?*ast.Node,1674 payload_token: ?ast.TokenIndex,
1510) InnerError!*zir.Inst {1675) InnerError!*zir.Inst {
1511 const tree = scope.tree();1676 const tree = scope.tree();
1677 const token_starts = tree.tokens.items(.start);
1678
1512 const src = token_starts[op_token];1679 const src = token_starts[op_token];
15131680
1514 var block_scope: Scope.GenZIR = .{1681 var block_scope: Scope.GenZIR = .{
...@@ -1547,12 +1714,11 @@ fn orelseCatchExpr(...@@ -1547,12 +1714,11 @@ fn orelseCatchExpr(
15471714
1548 var err_val_scope: Scope.LocalVal = undefined;1715 var err_val_scope: Scope.LocalVal = undefined;
1549 const then_sub_scope = blk: {1716 const then_sub_scope = blk: {
1550 const payload = payload_node orelse break :blk &then_scope.base;1717 const payload = payload_token orelse break :blk &then_scope.base;
15511718 if (mem.eql(u8, tree.tokenSlice(payload), "_")) {
1552 const err_name = tree.tokenSlice(payload.castTag(.Payload).?.error_symbol.firstToken());1719 return mod.failTok(&then_scope.base, payload, "discard of error capture; omit it instead", .{});
1553 if (mem.eql(u8, err_name, "_"))1720 }
1554 break :blk &then_scope.base;1721 const err_name = try mod.identifierTokenString(scope, payload);
1555
1556 err_val_scope = .{1722 err_val_scope = .{
1557 .parent = &then_scope.base,1723 .parent = &then_scope.base,
1558 .gen_zir = &then_scope,1724 .gen_zir = &then_scope,
...@@ -1685,18 +1851,20 @@ pub fn field(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) I...@@ -1685,18 +1851,20 @@ pub fn field(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) I
1685 const tree = scope.tree();1851 const tree = scope.tree();
1686 const token_starts = tree.tokens.items(.start);1852 const token_starts = tree.tokens.items(.start);
1687 const main_tokens = tree.nodes.items(.main_token);1853 const main_tokens = tree.nodes.items(.main_token);
1854 const node_datas = tree.nodes.items(.data);
1855
1688 const dot_token = main_tokens[node];1856 const dot_token = main_tokens[node];
1689 const src = token_starts[dot_token];1857 const src = token_starts[dot_token];
1690 const field_ident = dot_token + 1;1858 const field_ident = dot_token + 1;
1691 const field_name = try mod.identifierTokenString(scope, field_ident);1859 const field_name = try mod.identifierTokenString(scope, field_ident);
1692 if (rl == .ref) {1860 if (rl == .ref) {
1693 return addZirInstTag(mod, scope, src, .field_ptr, .{1861 return addZirInstTag(mod, scope, src, .field_ptr, .{
1694 .object = try expr(mod, scope, .ref, node.lhs),1862 .object = try expr(mod, scope, .ref, node_datas[node].lhs),
1695 .field_name = field_name,1863 .field_name = field_name,
1696 });1864 });
1697 } else {1865 } else {
1698 return rvalue(mod, scope, rl, try addZirInstTag(mod, scope, src, .field_val, .{1866 return rvalue(mod, scope, rl, try addZirInstTag(mod, scope, src, .field_val, .{
1699 .object = try expr(mod, scope, .none, node.lhs),1867 .object = try expr(mod, scope, .none, node_datas[node].lhs),
1700 .field_name = field_name,1868 .field_name = field_name,
1701 }));1869 }));
1702 }1870 }
...@@ -1711,6 +1879,8 @@ fn arrayAccess(...@@ -1711,6 +1879,8 @@ fn arrayAccess(
1711 const tree = scope.tree();1879 const tree = scope.tree();
1712 const main_tokens = tree.nodes.items(.main_token);1880 const main_tokens = tree.nodes.items(.main_token);
1713 const token_starts = tree.tokens.items(.start);1881 const token_starts = tree.tokens.items(.start);
1882 const node_datas = tree.nodes.items(.data);
1883
1714 const src = token_starts[main_tokens[node]];1884 const src = token_starts[main_tokens[node]];
1715 const usize_type = try addZIRInstConst(mod, scope, src, .{1885 const usize_type = try addZIRInstConst(mod, scope, src, .{
1716 .ty = Type.initTag(.type),1886 .ty = Type.initTag(.type),
...@@ -1737,6 +1907,7 @@ fn sliceExpr(...@@ -1737,6 +1907,7 @@ fn sliceExpr(
1737) InnerError!*zir.Inst {1907) InnerError!*zir.Inst {
1738 const tree = scope.tree();1908 const tree = scope.tree();
1739 const token_starts = tree.tokens.items(.start);1909 const token_starts = tree.tokens.items(.start);
1910
1740 const src = token_starts[slice.ast.lbracket];1911 const src = token_starts[slice.ast.lbracket];
17411912
1742 const usize_type = try addZIRInstConst(mod, scope, src, .{1913 const usize_type = try addZIRInstConst(mod, scope, src, .{
...@@ -1786,6 +1957,7 @@ fn simpleBinOp(...@@ -1786,6 +1957,7 @@ fn simpleBinOp(
1786 const tree = scope.tree();1957 const tree = scope.tree();
1787 const node_datas = tree.nodes.items(.data);1958 const node_datas = tree.nodes.items(.data);
1788 const main_tokens = tree.nodes.items(.main_token);1959 const main_tokens = tree.nodes.items(.main_token);
1960 const token_starts = tree.tokens.items(.start);
17891961
1790 const lhs = try expr(mod, scope, .none, node_datas[infix_node].lhs);1962 const lhs = try expr(mod, scope, .none, node_datas[infix_node].lhs);
1791 const rhs = try expr(mod, scope, .none, node_datas[infix_node].rhs);1963 const rhs = try expr(mod, scope, .none, node_datas[infix_node].rhs);
...@@ -1804,6 +1976,7 @@ fn boolBinOp(...@@ -1804,6 +1976,7 @@ fn boolBinOp(
1804 const tree = scope.tree();1976 const tree = scope.tree();
1805 const node_datas = tree.nodes.items(.data);1977 const node_datas = tree.nodes.items(.data);
1806 const main_tokens = tree.nodes.items(.main_token);1978 const main_tokens = tree.nodes.items(.main_token);
1979 const token_starts = tree.tokens.items(.start);
18071980
1808 const src = token_starts[main_tokens[infix_node]];1981 const src = token_starts[main_tokens[infix_node]];
1809 const bool_type = try addZIRInstConst(mod, scope, src, .{1982 const bool_type = try addZIRInstConst(mod, scope, src, .{
...@@ -1899,13 +2072,14 @@ fn ifExpr(...@@ -1899,13 +2072,14 @@ fn ifExpr(
1899 defer block_scope.instructions.deinit(mod.gpa);2072 defer block_scope.instructions.deinit(mod.gpa);
19002073
1901 const tree = scope.tree();2074 const tree = scope.tree();
1902 const node_datas = tree.nodes.items(.data);
1903 const main_tokens = tree.nodes.items(.main_token);2075 const main_tokens = tree.nodes.items(.main_token);
2076 const token_starts = tree.tokens.items(.start);
2077
1904 const if_src = token_starts[if_full.ast.if_token];2078 const if_src = token_starts[if_full.ast.if_token];
19052079
1906 const cond = c: {2080 const cond = c: {
1907 // TODO https://github.com/ziglang/zig/issues/79292081 // TODO https://github.com/ziglang/zig/issues/7929
1908 if (if_full.ast.error_token) |error_token| {2082 if (if_full.error_token) |error_token| {
1909 return mod.failTok(scope, error_token, "TODO implement if error union", .{});2083 return mod.failTok(scope, error_token, "TODO implement if error union", .{});
1910 } else if (if_full.payload_token) |payload_token| {2084 } else if (if_full.payload_token) |payload_token| {
1911 return mod.failTok(scope, payload_token, "TODO implement if optional", .{});2085 return mod.failTok(scope, payload_token, "TODO implement if optional", .{});
...@@ -1966,7 +2140,7 @@ fn ifExpr(...@@ -1966,7 +2140,7 @@ fn ifExpr(
1966 };2140 };
1967 } else2141 } else
1968 .{2142 .{
1969 .src = token_starts[tree.lastToken(if_full.then_expr)],2143 .src = token_starts[tree.lastToken(if_full.ast.then_expr)],
1970 .result = null,2144 .result = null,
1971 };2145 };
19722146
...@@ -2042,8 +2216,9 @@ fn whileExpr(...@@ -2042,8 +2216,9 @@ fn whileExpr(
2042 defer continue_scope.instructions.deinit(mod.gpa);2216 defer continue_scope.instructions.deinit(mod.gpa);
20432217
2044 const tree = scope.tree();2218 const tree = scope.tree();
2045 const node_datas = tree.nodes.items(.data);
2046 const main_tokens = tree.nodes.items(.main_token);2219 const main_tokens = tree.nodes.items(.main_token);
2220 const token_starts = tree.tokens.items(.start);
2221
2047 const while_src = token_starts[while_full.ast.while_token];2222 const while_src = token_starts[while_full.ast.while_token];
2048 const void_type = try addZIRInstConst(mod, scope, while_src, .{2223 const void_type = try addZIRInstConst(mod, scope, while_src, .{
2049 .ty = Type.initTag(.type),2224 .ty = Type.initTag(.type),
...@@ -2051,16 +2226,16 @@ fn whileExpr(...@@ -2051,16 +2226,16 @@ fn whileExpr(
2051 });2226 });
2052 const cond = c: {2227 const cond = c: {
2053 // TODO https://github.com/ziglang/zig/issues/79292228 // TODO https://github.com/ziglang/zig/issues/7929
2054 if (while_full.ast.error_token) |error_token| {2229 if (while_full.error_token) |error_token| {
2055 return mod.failTok(scope, error_token, "TODO implement while error union", .{});2230 return mod.failTok(scope, error_token, "TODO implement while error union", .{});
2056 } else if (while_full.payload_token) |payload_token| {2231 } else if (while_full.payload_token) |payload_token| {
2057 return mod.failTok(scope, payload_token, "TODO implement while optional", .{});2232 return mod.failTok(scope, payload_token, "TODO implement while optional", .{});
2058 } else {2233 } else {
2059 const bool_type = try addZIRInstConst(mod, &block_scope.base, while_src, .{2234 const bool_type = try addZIRInstConst(mod, &continue_scope.base, while_src, .{
2060 .ty = Type.initTag(.type),2235 .ty = Type.initTag(.type),
2061 .val = Value.initTag(.bool_type),2236 .val = Value.initTag(.bool_type),
2062 });2237 });
2063 break :c try expr(mod, &block_scope.base, .{ .ty = bool_type }, while_full.ast.cond_expr);2238 break :c try expr(mod, &continue_scope.base, .{ .ty = bool_type }, while_full.ast.cond_expr);
2064 }2239 }
2065 };2240 };
20662241
...@@ -2128,7 +2303,7 @@ fn whileExpr(...@@ -2128,7 +2303,7 @@ fn whileExpr(
2128 };2303 };
2129 defer else_scope.instructions.deinit(mod.gpa);2304 defer else_scope.instructions.deinit(mod.gpa);
21302305
2131 const else_node = if_full.ast.else_expr;2306 const else_node = while_full.ast.else_expr;
2132 const else_info: struct { src: usize, result: ?*zir.Inst } = if (else_node != 0) blk: {2307 const else_info: struct { src: usize, result: ?*zir.Inst } = if (else_node != 0) blk: {
2133 loop_scope.break_count += 1;2308 loop_scope.break_count += 1;
2134 const sub_scope = &else_scope.base;2309 const sub_scope = &else_scope.base;
...@@ -2138,7 +2313,7 @@ fn whileExpr(...@@ -2138,7 +2313,7 @@ fn whileExpr(
2138 };2313 };
2139 } else2314 } else
2140 .{2315 .{
2141 .src = token_starts[tree.lastToken(then_node)],2316 .src = token_starts[tree.lastToken(while_full.ast.then_expr)],
2142 .result = null,2317 .result = null,
2143 };2318 };
21442319
...@@ -2181,8 +2356,10 @@ fn forExpr(...@@ -2181,8 +2356,10 @@ fn forExpr(
21812356
2182 // Set up variables and constants.2357 // Set up variables and constants.
2183 const tree = scope.tree();2358 const tree = scope.tree();
2184 const node_datas = tree.nodes.items(.data);
2185 const main_tokens = tree.nodes.items(.main_token);2359 const main_tokens = tree.nodes.items(.main_token);
2360 const token_starts = tree.tokens.items(.start);
2361 const token_tags = tree.tokens.items(.tag);
2362
2186 const for_src = token_starts[for_full.ast.while_token];2363 const for_src = token_starts[for_full.ast.while_token];
2187 const index_ptr = blk: {2364 const index_ptr = blk: {
2188 const usize_type = try addZIRInstConst(mod, scope, for_src, .{2365 const usize_type = try addZIRInstConst(mod, scope, for_src, .{
...@@ -2299,7 +2476,7 @@ fn forExpr(...@@ -2299,7 +2476,7 @@ fn forExpr(
2299 else2476 else
2300 break :blk &then_scope.base;2477 break :blk &then_scope.base;
2301 if (mem.eql(u8, tree.tokenSlice(index_token), "_")) {2478 if (mem.eql(u8, tree.tokenSlice(index_token), "_")) {
2302 return mod.failTok(&then_scope.base, index_token, "discard of index capture not allowed; omit it instead", .{});2479 return mod.failTok(&then_scope.base, index_token, "discard of index capture; omit it instead", .{});
2303 }2480 }
2304 const index_name = try mod.identifierTokenString(&then_scope.base, index_token);2481 const index_name = try mod.identifierTokenString(&then_scope.base, index_token);
2305 index_scope = .{2482 index_scope = .{
...@@ -2334,7 +2511,7 @@ fn forExpr(...@@ -2334,7 +2511,7 @@ fn forExpr(
2334 };2511 };
2335 } else2512 } else
2336 .{2513 .{
2337 .src = token_starts[tree.lastToken(then_node)],2514 .src = token_starts[tree.lastToken(for_full.ast.then_expr)],
2338 .result = null,2515 .result = null,
2339 };2516 };
23402517
...@@ -2386,10 +2563,12 @@ fn switchExpr(...@@ -2386,10 +2563,12 @@ fn switchExpr(
2386 const node_datas = tree.nodes.items(.data);2563 const node_datas = tree.nodes.items(.data);
2387 const main_tokens = tree.nodes.items(.main_token);2564 const main_tokens = tree.nodes.items(.main_token);
2388 const token_tags = tree.tokens.items(.tag);2565 const token_tags = tree.tokens.items(.tag);
2566 const token_starts = tree.tokens.items(.start);
2567 const node_tags = tree.nodes.items(.tag);
23892568
2390 const switch_token = main_tokens[switch_node];2569 const switch_token = main_tokens[switch_node];
2391 const target_node = datas[switch_node].lhs;2570 const target_node = node_datas[switch_node].lhs;
2392 const extra = tree.extraData(datas[switch_node].rhs, ast.switch_node.SubRange);2571 const extra = tree.extraData(node_datas[switch_node].rhs, ast.Node.SubRange);
2393 const case_nodes = tree.extra_data[extra.start..extra.end];2572 const case_nodes = tree.extra_data[extra.start..extra.end];
23942573
2395 const switch_src = token_starts[switch_token];2574 const switch_src = token_starts[switch_token];
...@@ -2552,7 +2731,7 @@ fn switchExpr(...@@ -2552,7 +2731,7 @@ fn switchExpr(
2552 defer else_scope.instructions.deinit(mod.gpa);2731 defer else_scope.instructions.deinit(mod.gpa);
25532732
2554 // Now generate all but the special cases.2733 // Now generate all but the special cases.
2555 var special_case: ?ast.Node.Index = null;2734 var special_case: ?ast.full.SwitchCase = null;
2556 var items_index: usize = 0;2735 var items_index: usize = 0;
2557 var case_index: usize = 0;2736 var case_index: usize = 0;
2558 for (case_nodes) |case_node| {2737 for (case_nodes) |case_node| {
...@@ -2582,7 +2761,7 @@ fn switchExpr(...@@ -2582,7 +2761,7 @@ fn switchExpr(
2582 {2761 {
2583 const item = items.items[items_index];2762 const item = items.items[items_index];
2584 items_index += 1;2763 items_index += 1;
2585 try switchCaseExpr(mod, &case_scope.base, block_scope.break_result_loc, block, case, target, target_ptr);2764 try switchCaseExpr(mod, &case_scope.base, block_scope.break_result_loc, block, case, target);
25862765
2587 cases[case_index] = .{2766 cases[case_index] = .{
2588 .item = item,2767 .item = item,
...@@ -2638,7 +2817,7 @@ fn switchExpr(...@@ -2638,7 +2817,7 @@ fn switchExpr(
26382817
2639 // reset cond_scope for then_body2818 // reset cond_scope for then_body
2640 case_scope.instructions.items.len = 0;2819 case_scope.instructions.items.len = 0;
2641 try switchCaseExpr(mod, &case_scope.base, block_scope.break_result_loc, block, case, target, target_ptr);2820 try switchCaseExpr(mod, &case_scope.base, block_scope.break_result_loc, block, case, target);
2642 condbr.positionals.then_body = .{2821 condbr.positionals.then_body = .{
2643 .instructions = try scope.arena().dupe(*zir.Inst, case_scope.instructions.items),2822 .instructions = try scope.arena().dupe(*zir.Inst, case_scope.instructions.items),
2644 };2823 };
...@@ -2655,7 +2834,7 @@ fn switchExpr(...@@ -2655,7 +2834,7 @@ fn switchExpr(
26552834
2656 // Finally generate else block or a break.2835 // Finally generate else block or a break.
2657 if (special_case) |case| {2836 if (special_case) |case| {
2658 try switchCaseExpr(mod, &else_scope.base, block_scope.break_result_loc, block, case, target, target_ptr);2837 try switchCaseExpr(mod, &else_scope.base, block_scope.break_result_loc, block, case, target);
2659 } else {2838 } else {
2660 // Not handling all possible cases is a compile error.2839 // Not handling all possible cases is a compile error.
2661 _ = try addZIRNoOp(mod, &else_scope.base, switch_src, .unreachable_unsafe);2840 _ = try addZIRNoOp(mod, &else_scope.base, switch_src, .unreachable_unsafe);
...@@ -2674,11 +2853,13 @@ fn switchCaseExpr(...@@ -2674,11 +2853,13 @@ fn switchCaseExpr(
2674 block: *zir.Inst.Block,2853 block: *zir.Inst.Block,
2675 case: ast.full.SwitchCase,2854 case: ast.full.SwitchCase,
2676 target: *zir.Inst,2855 target: *zir.Inst,
2677 target_ptr: ?*zir.Inst,
2678) !void {2856) !void {
2679 const tree = scope.tree();2857 const tree = scope.tree();
2680 const node_datas = tree.nodes.items(.data);2858 const node_datas = tree.nodes.items(.data);
2681 const main_tokens = tree.nodes.items(.main_token);2859 const main_tokens = tree.nodes.items(.main_token);
2860 const token_starts = tree.tokens.items(.start);
2861 const token_tags = tree.tokens.items(.tag);
2862
2682 const case_src = token_starts[case.ast.arrow_token];2863 const case_src = token_starts[case.ast.arrow_token];
2683 const sub_scope = blk: {2864 const sub_scope = blk: {
2684 const payload_token = case.payload_token orelse break :blk scope;2865 const payload_token = case.payload_token orelse break :blk scope;
...@@ -2690,11 +2871,11 @@ fn switchCaseExpr(...@@ -2690,11 +2871,11 @@ fn switchCaseExpr(
2690 const value_name = tree.tokenSlice(ident);2871 const value_name = tree.tokenSlice(ident);
2691 if (mem.eql(u8, value_name, "_")) {2872 if (mem.eql(u8, value_name, "_")) {
2692 if (is_ptr) {2873 if (is_ptr) {
2693 return mod.failTok(scope, payload.ptr_token.?, "pointer modifier invalid on discard", .{});2874 return mod.failTok(scope, payload_token, "pointer modifier invalid on discard", .{});
2694 }2875 }
2695 break :blk scope;2876 break :blk scope;
2696 }2877 }
2697 return mod.failNode(scope, payload.value_symbol, "TODO implement switch value payload", .{});2878 return mod.failTok(scope, ident, "TODO implement switch value payload", .{});
2698 };2879 };
26992880
2700 const case_body = try expr(mod, sub_scope, rl, case.ast.target_expr);2881 const case_body = try expr(mod, sub_scope, rl, case.ast.target_expr);
...@@ -2710,10 +2891,12 @@ fn ret(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst {...@@ -2710,10 +2891,12 @@ fn ret(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst {
2710 const tree = scope.tree();2891 const tree = scope.tree();
2711 const node_datas = tree.nodes.items(.data);2892 const node_datas = tree.nodes.items(.data);
2712 const main_tokens = tree.nodes.items(.main_token);2893 const main_tokens = tree.nodes.items(.main_token);
2894 const token_starts = tree.tokens.items(.start);
2895
2713 const src = token_starts[main_tokens[node]];2896 const src = token_starts[main_tokens[node]];
2714 const rhs_node = node_datas[node].lhs;2897 const rhs_node = node_datas[node].lhs;
2715 if (rhs_node != 0) {2898 if (rhs_node != 0) {
2716 if (nodeMayNeedMemoryLocation(rhs_node, scope)) {2899 if (nodeMayNeedMemoryLocation(scope, rhs_node)) {
2717 const ret_ptr = try addZIRNoOp(mod, scope, src, .ret_ptr);2900 const ret_ptr = try addZIRNoOp(mod, scope, src, .ret_ptr);
2718 const operand = try expr(mod, scope, .{ .ptr = ret_ptr }, rhs_node);2901 const operand = try expr(mod, scope, .{ .ptr = ret_ptr }, rhs_node);
2719 return addZIRUnOp(mod, scope, src, .@"return", operand);2902 return addZIRUnOp(mod, scope, src, .@"return", operand);
...@@ -2737,8 +2920,8 @@ fn identifier(...@@ -2737,8 +2920,8 @@ fn identifier(
2737 defer tracy.end();2920 defer tracy.end();
27382921
2739 const tree = scope.tree();2922 const tree = scope.tree();
2740 const node_datas = tree.nodes.items(.data);
2741 const main_tokens = tree.nodes.items(.main_token);2923 const main_tokens = tree.nodes.items(.main_token);
2924 const token_starts = tree.tokens.items(.start);
27422925
2743 const ident_token = main_tokens[ident];2926 const ident_token = main_tokens[ident];
2744 const ident_name = try mod.identifierTokenString(scope, ident_token);2927 const ident_name = try mod.identifierTokenString(scope, ident_token);
...@@ -2826,6 +3009,27 @@ fn identifier(...@@ -2826,6 +3009,27 @@ fn identifier(
2826 return mod.failNode(scope, ident, "use of undeclared identifier '{s}'", .{ident_name});3009 return mod.failNode(scope, ident, "use of undeclared identifier '{s}'", .{ident_name});
2827}3010}
28283011
3012fn parseStringLiteral(mod: *Module, scope: *Scope, token: ast.TokenIndex) ![]u8 {
3013 const tree = scope.tree();
3014 const token_tags = tree.tokens.items(.tag);
3015 const token_starts = tree.tokens.items(.start);
3016 assert(token_tags[token] == .string_literal);
3017 const unparsed = tree.tokenSlice(token);
3018 const arena = scope.arena();
3019 var bad_index: usize = undefined;
3020 const bytes = std.zig.parseStringLiteral(arena, unparsed, &bad_index) catch |err| switch (err) {
3021 error.InvalidCharacter => {
3022 const bad_byte = unparsed[bad_index];
3023 const src = token_starts[token];
3024 return mod.fail(scope, src + bad_index, "invalid string literal character: '{c}'", .{
3025 bad_byte,
3026 });
3027 },
3028 else => |e| return e,
3029 };
3030 return bytes;
3031}
3032
2829fn stringLiteral(3033fn stringLiteral(
2830 mod: *Module,3034 mod: *Module,
2831 scope: *Scope,3035 scope: *Scope,
...@@ -2833,23 +3037,11 @@ fn stringLiteral(...@@ -2833,23 +3037,11 @@ fn stringLiteral(
2833 str_lit: ast.Node.Index,3037 str_lit: ast.Node.Index,
2834) InnerError!*zir.Inst {3038) InnerError!*zir.Inst {
2835 const tree = scope.tree();3039 const tree = scope.tree();
2836 const node_datas = tree.nodes.items(.data);
2837 const main_tokens = tree.nodes.items(.main_token);3040 const main_tokens = tree.nodes.items(.main_token);
3041 const token_starts = tree.tokens.items(.start);
28383042
2839 const str_lit_token = main_tokens[str_lit];3043 const str_lit_token = main_tokens[str_lit];
2840 const unparsed_bytes = tree.tokenSlice(str_lit_token);3044 const bytes = try parseStringLiteral(mod, scope, str_lit_token);
2841 const arena = scope.arena();
2842
2843 var bad_index: usize = undefined;
2844 const bytes = std.zig.parseStringLiteral(arena, unparsed_bytes, &bad_index) catch |err| switch (err) {
2845 error.InvalidCharacter => {
2846 const bad_byte = unparsed_bytes[bad_index];
2847 const src = token_starts[str_lit_token];
2848 return mod.fail(scope, src + bad_index, "invalid string literal character: '{c}'\n", .{bad_byte});
2849 },
2850 else => |e| return e,
2851 };
2852
2853 const src = token_starts[str_lit_token];3045 const src = token_starts[str_lit_token];
2854 const str_inst = try addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{});3046 const str_inst = try addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{});
2855 return rvalue(mod, scope, rl, str_inst);3047 return rvalue(mod, scope, rl, str_inst);
...@@ -2864,9 +3056,10 @@ fn multilineStringLiteral(...@@ -2864,9 +3056,10 @@ fn multilineStringLiteral(
2864 const tree = scope.tree();3056 const tree = scope.tree();
2865 const node_datas = tree.nodes.items(.data);3057 const node_datas = tree.nodes.items(.data);
2866 const main_tokens = tree.nodes.items(.main_token);3058 const main_tokens = tree.nodes.items(.main_token);
3059 const token_starts = tree.tokens.items(.start);
28673060
2868 const start = node_datas[node].lhs;3061 const start = node_datas[str_lit].lhs;
2869 const end = node_datas[node].rhs;3062 const end = node_datas[str_lit].rhs;
28703063
2871 // Count the number of bytes to allocate.3064 // Count the number of bytes to allocate.
2872 const len: usize = len: {3065 const len: usize = len: {
...@@ -2905,9 +3098,10 @@ fn multilineStringLiteral(...@@ -2905,9 +3098,10 @@ fn multilineStringLiteral(
29053098
2906fn charLiteral(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !*zir.Inst {3099fn charLiteral(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !*zir.Inst {
2907 const tree = scope.tree();3100 const tree = scope.tree();
2908 const node_datas = tree.nodes.items(.data);
2909 const main_tokens = tree.nodes.items(.main_token);3101 const main_tokens = tree.nodes.items(.main_token);
2910 const main_token = main_tokens[node];3102 const main_token = main_tokens[node];
3103 const token_starts = tree.tokens.items(.start);
3104
2911 const src = token_starts[main_token];3105 const src = token_starts[main_token];
2912 const slice = tree.tokenSlice(main_token);3106 const slice = tree.tokenSlice(main_token);
29133107
...@@ -2934,6 +3128,7 @@ fn integerLiteral(...@@ -2934,6 +3128,7 @@ fn integerLiteral(
2934 const arena = scope.arena();3128 const arena = scope.arena();
2935 const tree = scope.tree();3129 const tree = scope.tree();
2936 const main_tokens = tree.nodes.items(.main_token);3130 const main_tokens = tree.nodes.items(.main_token);
3131 const token_starts = tree.tokens.items(.start);
29373132
2938 const int_token = main_tokens[int_lit];3133 const int_token = main_tokens[int_lit];
2939 const prefixed_bytes = tree.tokenSlice(int_token);3134 const prefixed_bytes = tree.tokenSlice(int_token);
...@@ -2972,6 +3167,8 @@ fn floatLiteral(...@@ -2972,6 +3167,8 @@ fn floatLiteral(
2972 const arena = scope.arena();3167 const arena = scope.arena();
2973 const tree = scope.tree();3168 const tree = scope.tree();
2974 const main_tokens = tree.nodes.items(.main_token);3169 const main_tokens = tree.nodes.items(.main_token);
3170 const token_starts = tree.tokens.items(.start);
3171
2975 const main_token = main_tokens[float_lit];3172 const main_token = main_tokens[float_lit];
2976 const bytes = tree.tokenSlice(main_token);3173 const bytes = tree.tokenSlice(main_token);
2977 if (bytes.len > 2 and bytes[1] == 'x') {3174 if (bytes.len > 2 and bytes[1] == 'x') {
...@@ -2988,17 +3185,18 @@ fn floatLiteral(...@@ -2988,17 +3185,18 @@ fn floatLiteral(
2988 return rvalue(mod, scope, rl, result);3185 return rvalue(mod, scope, rl, result);
2989}3186}
29903187
2991fn assembly(mod: *Module, scope: *Scope, rl: ResultLoc, full: ast.full.Asm) InnerError!*zir.Inst {3188fn asmExpr(mod: *Module, scope: *Scope, rl: ResultLoc, full: ast.full.Asm) InnerError!*zir.Inst {
2992 const arena = scope.arena();3189 const arena = scope.arena();
2993 const tree = scope.tree();3190 const tree = scope.tree();
2994 const node_datas = tree.nodes.items(.data);
2995 const main_tokens = tree.nodes.items(.main_token);3191 const main_tokens = tree.nodes.items(.main_token);
3192 const token_starts = tree.tokens.items(.start);
3193 const node_datas = tree.nodes.items(.data);
29963194
2997 if (full.outputs.len != 0) {3195 if (full.outputs.len != 0) {
2998 return mod.failTok(scope, full.ast.asm_token, "TODO implement asm with an output", .{});3196 return mod.failTok(scope, full.ast.asm_token, "TODO implement asm with an output", .{});
2999 }3197 }
30003198
3001 const inputs = try arena.alloc(*zir.Inst, full.inputs.len);3199 const inputs = try arena.alloc([]const u8, full.inputs.len);
3002 const args = try arena.alloc(*zir.Inst, full.inputs.len);3200 const args = try arena.alloc(*zir.Inst, full.inputs.len);
30033201
3004 const src = token_starts[full.ast.asm_token];3202 const src = token_starts[full.ast.asm_token];
...@@ -3010,15 +3208,16 @@ fn assembly(mod: *Module, scope: *Scope, rl: ResultLoc, full: ast.full.Asm) Inne...@@ -3010,15 +3208,16 @@ fn assembly(mod: *Module, scope: *Scope, rl: ResultLoc, full: ast.full.Asm) Inne
30103208
3011 for (full.inputs) |input, i| {3209 for (full.inputs) |input, i| {
3012 // TODO semantically analyze constraints3210 // TODO semantically analyze constraints
3013 inputs[i] = try expr(mod, scope, str_type_rl, input.constraint);3211 const constraint_token = main_tokens[input] + 2;
3014 args[i] = try expr(mod, scope, .none, input.expr);3212 inputs[i] = try parseStringLiteral(mod, scope, constraint_token);
3213 args[i] = try expr(mod, scope, .none, node_datas[input].lhs);
3015 }3214 }
30163215
3017 const return_type = try addZIRInstConst(mod, scope, src, .{3216 const return_type = try addZIRInstConst(mod, scope, src, .{
3018 .ty = Type.initTag(.type),3217 .ty = Type.initTag(.type),
3019 .val = Value.initTag(.void_type),3218 .val = Value.initTag(.void_type),
3020 });3219 });
3021 const asm_inst = try addZIRInst(mod, scope, src, zir.Inst.@"asm", .{3220 const asm_inst = try addZIRInst(mod, scope, src, zir.Inst.Asm, .{
3022 .asm_source = try expr(mod, scope, str_type_rl, full.ast.template),3221 .asm_source = try expr(mod, scope, str_type_rl, full.ast.template),
3023 .return_type = return_type,3222 .return_type = return_type,
3024 }, .{3223 }, .{
...@@ -3185,8 +3384,9 @@ fn builtinCall(...@@ -3185,8 +3384,9 @@ fn builtinCall(
3185 params: []const ast.Node.Index,3384 params: []const ast.Node.Index,
3186) InnerError!*zir.Inst {3385) InnerError!*zir.Inst {
3187 const tree = scope.tree();3386 const tree = scope.tree();
3188 const node_datas = tree.nodes.items(.data);
3189 const main_tokens = tree.nodes.items(.main_token);3387 const main_tokens = tree.nodes.items(.main_token);
3388 const token_starts = tree.tokens.items(.start);
3389
3190 const builtin_token = main_tokens[call];3390 const builtin_token = main_tokens[call];
3191 const builtin_name = tree.tokenSlice(builtin_token);3391 const builtin_name = tree.tokenSlice(builtin_token);
31923392
...@@ -3200,11 +3400,13 @@ fn builtinCall(...@@ -3200,11 +3400,13 @@ fn builtinCall(
3200 builtin_name,3400 builtin_name,
3201 });3401 });
3202 };3402 };
3203 if (info.param_count != params.len) {3403 if (info.param_count) |expected| {
3204 const s = if (params.len == 1) "" else "s";3404 if (expected != params.len) {
3205 return mod.failTok(scope, builtin_token, "expected {d} parameter{s}, found {d}", .{3405 const s = if (expected == 1) "" else "s";
3206 expected, s, found,3406 return mod.failTok(scope, builtin_token, "expected {d} parameter{s}, found {d}", .{
3207 });3407 expected, s, params.len,
3408 });
3409 }
3208 }3410 }
3209 const src = token_starts[builtin_token];3411 const src = token_starts[builtin_token];
32103412
...@@ -3237,7 +3439,7 @@ fn builtinCall(...@@ -3237,7 +3439,7 @@ fn builtinCall(
3237 },3439 },
3238 .compile_error => {3440 .compile_error => {
3239 const target = try expr(mod, scope, .none, params[0]);3441 const target = try expr(mod, scope, .none, params[0]);
3240 const result = addZIRUnOp(mod, scope, src, .compile_error, target);3442 const result = try addZIRUnOp(mod, scope, src, .compile_error, target);
3241 return rvalue(mod, scope, rl, result);3443 return rvalue(mod, scope, rl, result);
3242 },3444 },
3243 .set_eval_branch_quota => {3445 .set_eval_branch_quota => {
...@@ -3386,8 +3588,9 @@ fn callExpr(...@@ -3386,8 +3588,9 @@ fn callExpr(
3386 }3588 }
33873589
3388 const tree = scope.tree();3590 const tree = scope.tree();
3389 const node_datas = tree.nodes.items(.data);
3390 const main_tokens = tree.nodes.items(.main_token);3591 const main_tokens = tree.nodes.items(.main_token);
3592 const token_starts = tree.tokens.items(.start);
3593
3391 const lhs = try expr(mod, scope, .none, call.ast.fn_expr);3594 const lhs = try expr(mod, scope, .none, call.ast.fn_expr);
33923595
3393 const args = try scope.getGenZIR().arena.alloc(*zir.Inst, call.ast.params.len);3596 const args = try scope.getGenZIR().arena.alloc(*zir.Inst, call.ast.params.len);
...@@ -3446,23 +3649,26 @@ fn getSimplePrimitiveValue(name: []const u8) ?TypedValue {...@@ -3446,23 +3649,26 @@ fn getSimplePrimitiveValue(name: []const u8) ?TypedValue {
3446 return null;3649 return null;
3447}3650}
34483651
3449fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {3652fn nodeMayNeedMemoryLocation(scope: *Scope, start_node: ast.Node.Index) bool {
3653 const tree = scope.tree();
3654 const node_tags = tree.nodes.items(.tag);
3655 const node_datas = tree.nodes.items(.data);
3656 const main_tokens = tree.nodes.items(.main_token);
3657 const token_tags = tree.tokens.items(.tag);
3658
3450 var node = start_node;3659 var node = start_node;
3451 while (true) {3660 while (true) {
3452 switch (node.tag) {3661 switch (node_tags[node]) {
3453 .Root,3662 .root,
3454 .@"usingnamespace",3663 .@"usingnamespace",
3455 .test_decl,3664 .test_decl,
3456 .doc_comment,
3457 .switch_case,3665 .switch_case,
3458 .switch_else,3666 .switch_case_one,
3459 .Else,3667 .container_field_init,
3460 .Payload,3668 .container_field_align,
3461 .PointerPayload,3669 .container_field,
3462 .PointerIndexPayload,3670 .asm_output,
3463 .ContainerField,3671 .asm_input,
3464 .ErrorTag,
3465 .FieldInitializer,
3466 => unreachable,3672 => unreachable,
34673673
3468 .@"return",3674 .@"return",
...@@ -3470,8 +3676,12 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {...@@ -3470,8 +3676,12 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
3470 .@"continue",3676 .@"continue",
3471 .bit_not,3677 .bit_not,
3472 .bool_not,3678 .bool_not,
3473 .var_decl,3679 .global_var_decl,
3680 .local_var_decl,
3681 .simple_var_decl,
3682 .aligned_var_decl,
3474 .@"defer",3683 .@"defer",
3684 .@"errdefer",
3475 .address_of,3685 .address_of,
3476 .optional_type,3686 .optional_type,
3477 .negation,3687 .negation,
...@@ -3479,27 +3689,46 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {...@@ -3479,27 +3689,46 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
3479 .@"resume",3689 .@"resume",
3480 .array_type,3690 .array_type,
3481 .array_type_sentinel,3691 .array_type_sentinel,
3482 .PtrType,3692 .ptr_type_aligned,
3483 .slice_type,3693 .ptr_type_sentinel,
3694 .ptr_type,
3695 .ptr_type_bit_range,
3484 .@"suspend",3696 .@"suspend",
3485 .@"anytype",3697 .@"anytype",
3486 .error_type,3698 .fn_proto_simple,
3487 .FnProto,3699 .fn_proto_multi,
3700 .fn_proto_one,
3701 .fn_proto,
3702 .fn_decl,
3488 .anyframe_type,3703 .anyframe_type,
3704 .anyframe_literal,
3489 .integer_literal,3705 .integer_literal,
3490 .float_literal,3706 .float_literal,
3491 .enum_literal,3707 .enum_literal,
3492 .string_literal,3708 .string_literal,
3493 .MultilineStringLiteral,3709 .multiline_string_literal,
3494 .char_literal,3710 .char_literal,
3495 .bool_literal,3711 .true_literal,
3712 .false_literal,
3496 .null_literal,3713 .null_literal,
3497 .undefined_literal,3714 .undefined_literal,
3498 .@"unreachable",3715 .unreachable_literal,
3499 .identifier,3716 .identifier,
3500 .error_set_decl,3717 .error_set_decl,
3501 .ContainerDecl,3718 .container_decl,
3719 .container_decl_comma,
3720 .container_decl_two,
3721 .container_decl_two_comma,
3722 .container_decl_arg,
3723 .container_decl_arg_comma,
3724 .tagged_union,
3725 .tagged_union_comma,
3726 .tagged_union_two,
3727 .tagged_union_two_comma,
3728 .tagged_union_enum_tag,
3729 .tagged_union_enum_tag_comma,
3502 .@"asm",3730 .@"asm",
3731 .asm_simple,
3503 .add,3732 .add,
3504 .add_wrap,3733 .add_wrap,
3505 .array_cat,3734 .array_cat,
...@@ -3537,14 +3766,16 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {...@@ -3537,14 +3766,16 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
3537 .mod,3766 .mod,
3538 .mul,3767 .mul,
3539 .mul_wrap,3768 .mul_wrap,
3540 .range,3769 .switch_range,
3541 .period,3770 .field_access,
3542 .sub,3771 .sub,
3543 .sub_wrap,3772 .sub_wrap,
3544 .slice,3773 .slice,
3774 .slice_open,
3775 .slice_sentinel,
3545 .deref,3776 .deref,
3546 .array_access,3777 .array_access,
3547 .block,3778 .error_value,
3548 .while_simple, // This variant cannot have an else expression.3779 .while_simple, // This variant cannot have an else expression.
3549 .while_cont, // This variant cannot have an else expression.3780 .while_cont, // This variant cannot have an else expression.
3550 .for_simple, // This variant cannot have an else expression.3781 .for_simple, // This variant cannot have an else expression.
...@@ -3558,18 +3789,30 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {...@@ -3558,18 +3789,30 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
3558 .@"comptime",3789 .@"comptime",
3559 .@"nosuspend",3790 .@"nosuspend",
3560 .unwrap_optional,3791 .unwrap_optional,
3561 => node = datas[node].lhs,3792 => node = node_datas[node].lhs,
35623793
3563 // Forward the question to the RHS sub-expression.3794 // Forward the question to the RHS sub-expression.
3564 .@"catch",3795 .@"catch",
3565 .@"orelse",3796 .@"orelse",
3566 => node = datas[node].rhs,3797 => node = node_datas[node].rhs,
35673798
3568 // True because these are exactly the expressions we need memory locations for.3799 // True because these are exactly the expressions we need memory locations for.
3569 .ArrayInitializer,3800 .array_init_one,
3570 .ArrayInitializerDot,3801 .array_init_one_comma,
3571 .StructInitializer,3802 .array_init_dot_two,
3572 .StructInitializerDot,3803 .array_init_dot_two_comma,
3804 .array_init_dot,
3805 .array_init_dot_comma,
3806 .array_init,
3807 .array_init_comma,
3808 .struct_init_one,
3809 .struct_init_one_comma,
3810 .struct_init_dot_two,
3811 .struct_init_dot_two_comma,
3812 .struct_init_dot,
3813 .struct_init_dot_comma,
3814 .struct_init,
3815 .struct_init_comma,
3573 => return true,3816 => return true,
35743817
3575 // True because depending on comptime conditions, sub-expressions3818 // True because depending on comptime conditions, sub-expressions
...@@ -3578,6 +3821,7 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {...@@ -3578,6 +3821,7 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
3578 .@"if", // This variant always has an else expression.3821 .@"if", // This variant always has an else expression.
3579 .@"for", // This variant always has an else expression.3822 .@"for", // This variant always has an else expression.
3580 .@"switch",3823 .@"switch",
3824 .switch_comma,
3581 .call_one,3825 .call_one,
3582 .call_one_comma,3826 .call_one_comma,
3583 .async_call_one,3827 .async_call_one,
...@@ -3588,10 +3832,10 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {...@@ -3588,10 +3832,10 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
3588 .async_call_comma,3832 .async_call_comma,
3589 => return true,3833 => return true,
35903834
3591 block_two,3835 .block_two,
3592 block_two_semicolon,3836 .block_two_semicolon,
3593 block,3837 .block,
3594 block_semicolon,3838 .block_semicolon,
3595 => {3839 => {
3596 const lbrace = main_tokens[node];3840 const lbrace = main_tokens[node];
3597 if (token_tags[lbrace - 1] == .colon) {3841 if (token_tags[lbrace - 1] == .colon) {
...@@ -3603,7 +3847,11 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {...@@ -3603,7 +3847,11 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
3603 }3847 }
3604 },3848 },
36053849
3606 .builtin_call => {3850 .builtin_call,
3851 .builtin_call_comma,
3852 .builtin_call_two,
3853 .builtin_call_two_comma,
3854 => {
3607 const builtin_token = main_tokens[node];3855 const builtin_token = main_tokens[node];
3608 const builtin_name = tree.tokenSlice(builtin_token);3856 const builtin_name = tree.tokenSlice(builtin_token);
3609 // If the builtin is an invalid name, we don't cause an error here; instead3857 // If the builtin is an invalid name, we don't cause an error here; instead
...@@ -3661,7 +3909,6 @@ fn rvalueVoid(...@@ -3661,7 +3909,6 @@ fn rvalueVoid(
3661 result: void,3909 result: void,
3662) InnerError!*zir.Inst {3910) InnerError!*zir.Inst {
3663 const tree = scope.tree();3911 const tree = scope.tree();
3664 const node_datas = tree.nodes.items(.data);
3665 const main_tokens = tree.nodes.items(.main_token);3912 const main_tokens = tree.nodes.items(.main_token);
3666 const src = tree.tokens.items(.start)[tree.firstToken(node)];3913 const src = tree.tokens.items(.start)[tree.firstToken(node)];
3667 const void_inst = try addZIRInstConst(mod, scope, src, .{3914 const void_inst = try addZIRInstConst(mod, scope, src, .{
...@@ -3765,7 +4012,7 @@ pub fn addZirInstT(...@@ -3765,7 +4012,7 @@ pub fn addZirInstT(
3765 src: usize,4012 src: usize,
3766 comptime T: type,4013 comptime T: type,
3767 tag: zir.Inst.Tag,4014 tag: zir.Inst.Tag,
3768 positionals: std.meta.fieldInfo(tag.Type(), .positionals).field_type,4015 positionals: std.meta.fieldInfo(T, .positionals).field_type,
3769) !*T {4016) !*T {
3770 const gen_zir = scope.getGenZIR();4017 const gen_zir = scope.getGenZIR();
3771 try gen_zir.instructions.ensureCapacity(mod.gpa, gen_zir.instructions.items.len + 1);4018 try gen_zir.instructions.ensureCapacity(mod.gpa, gen_zir.instructions.items.len + 1);
src/zir.zig+5-11
...@@ -863,8 +863,8 @@ pub const Inst = struct {...@@ -863,8 +863,8 @@ pub const Inst = struct {
863 kw_args: struct {863 kw_args: struct {
864 @"volatile": bool = false,864 @"volatile": bool = false,
865 output: ?*Inst = null,865 output: ?*Inst = null,
866 inputs: []*Inst = &[0]*Inst{},866 inputs: []const []const u8 = &.{},
867 clobbers: []*Inst = &[0]*Inst{},867 clobbers: []const []const u8 = &.{},
868 args: []*Inst = &[0]*Inst{},868 args: []*Inst = &[0]*Inst{},
869 },869 },
870 };870 };
...@@ -1192,16 +1192,9 @@ pub const Inst = struct {...@@ -1192,16 +1192,9 @@ pub const Inst = struct {
1192 },1192 },
1193 kw_args: struct {1193 kw_args: struct {
1194 init_inst: ?*Inst = null,1194 init_inst: ?*Inst = null,
1195 init_kind: InitKind = .none,1195 has_enum_token: bool,
1196 layout: std.builtin.TypeInfo.ContainerLayout = .Auto,1196 layout: std.builtin.TypeInfo.ContainerLayout = .Auto,
1197 },1197 },
1198
1199 // TODO error: values of type '(enum literal)' must be comptime known
1200 pub const InitKind = enum {
1201 enum_type,
1202 tag_type,
1203 none,
1204 };
1205 };1198 };
12061199
1207 pub const SwitchBr = struct {1200 pub const SwitchBr = struct {
...@@ -1413,6 +1406,7 @@ const Writer = struct {...@@ -1413,6 +1406,7 @@ const Writer = struct {
1413 }1406 }
1414 switch (@TypeOf(param)) {1407 switch (@TypeOf(param)) {
1415 *Inst => return self.writeInstParamToStream(stream, param),1408 *Inst => return self.writeInstParamToStream(stream, param),
1409 ?*Inst => return self.writeInstParamToStream(stream, param.?),
1416 []*Inst => {1410 []*Inst => {
1417 try stream.writeByte('[');1411 try stream.writeByte('[');
1418 for (param) |inst, i| {1412 for (param) |inst, i| {
...@@ -1480,7 +1474,7 @@ const Writer = struct {...@@ -1480,7 +1474,7 @@ const Writer = struct {
1480 const name = self.loop_table.get(param).?;1474 const name = self.loop_table.get(param).?;
1481 return stream.print("\"{}\"", .{std.zig.fmtEscapes(name)});1475 return stream.print("\"{}\"", .{std.zig.fmtEscapes(name)});
1482 },1476 },
1483 [][]const u8 => {1477 [][]const u8, []const []const u8 => {
1484 try stream.writeByte('[');1478 try stream.writeByte('[');
1485 for (param) |str, i| {1479 for (param) |str, i| {
1486 if (i != 0) {1480 if (i != 0) {
src/zir_sema.zig+7-5
...@@ -2023,19 +2023,21 @@ fn zirDeref(mod: *Module, scope: *Scope, deref: *zir.Inst.UnOp) InnerError!*Inst...@@ -2023,19 +2023,21 @@ fn zirDeref(mod: *Module, scope: *Scope, deref: *zir.Inst.UnOp) InnerError!*Inst
2023fn zirAsm(mod: *Module, scope: *Scope, assembly: *zir.Inst.Asm) InnerError!*Inst {2023fn zirAsm(mod: *Module, scope: *Scope, assembly: *zir.Inst.Asm) InnerError!*Inst {
2024 const tracy = trace(@src());2024 const tracy = trace(@src());
2025 defer tracy.end();2025 defer tracy.end();
2026
2026 const return_type = try resolveType(mod, scope, assembly.positionals.return_type);2027 const return_type = try resolveType(mod, scope, assembly.positionals.return_type);
2027 const asm_source = try resolveConstString(mod, scope, assembly.positionals.asm_source);2028 const asm_source = try resolveConstString(mod, scope, assembly.positionals.asm_source);
2028 const output = if (assembly.kw_args.output) |o| try resolveConstString(mod, scope, o) else null;2029 const output = if (assembly.kw_args.output) |o| try resolveConstString(mod, scope, o) else null;
20292030
2030 const inputs = try scope.arena().alloc([]const u8, assembly.kw_args.inputs.len);2031 const arena = scope.arena();
2031 const clobbers = try scope.arena().alloc([]const u8, assembly.kw_args.clobbers.len);2032 const inputs = try arena.alloc([]const u8, assembly.kw_args.inputs.len);
2032 const args = try scope.arena().alloc(*Inst, assembly.kw_args.args.len);2033 const clobbers = try arena.alloc([]const u8, assembly.kw_args.clobbers.len);
2034 const args = try arena.alloc(*Inst, assembly.kw_args.args.len);
20332035
2034 for (inputs) |*elem, i| {2036 for (inputs) |*elem, i| {
2035 elem.* = try resolveConstString(mod, scope, assembly.kw_args.inputs[i]);2037 elem.* = try arena.dupe(u8, assembly.kw_args.inputs[i]);
2036 }2038 }
2037 for (clobbers) |*elem, i| {2039 for (clobbers) |*elem, i| {
2038 elem.* = try resolveConstString(mod, scope, assembly.kw_args.clobbers[i]);2040 elem.* = try arena.dupe(u8, assembly.kw_args.clobbers[i]);
2039 }2041 }
2040 for (args) |*elem, i| {2042 for (args) |*elem, i| {
2041 const arg = try resolveInst(mod, scope, assembly.kw_args.args[i]);2043 const arg = try resolveInst(mod, scope, assembly.kw_args.args[i]);