authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-08-30 19:22:04-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-01 17:54:07-07:00
log3940a1be18a8312dec9d521c6e30ec4d34c44bd6
tree42344ba8a3b3e5eaea1f572a725391f98c36e72c
parente41e75a4862e955266a7e760133ea757e5afb8ce

rename std.zig.ast to std.zig.Ast; use top-level fields


15 files changed, 3396 insertions(+), 3396 deletions(-)

CMakeLists.txt+1-1
......@@ -529,7 +529,7 @@ set(ZIG_STAGE2_SOURCES
529529 "${CMAKE_SOURCE_DIR}/lib/std/time.zig"
530530 "${CMAKE_SOURCE_DIR}/lib/std/unicode.zig"
531531 "${CMAKE_SOURCE_DIR}/lib/std/zig.zig"
532 "${CMAKE_SOURCE_DIR}/lib/std/zig/ast.zig"
532 "${CMAKE_SOURCE_DIR}/lib/std/zig/Ast.zig"
533533 "${CMAKE_SOURCE_DIR}/lib/std/zig/cross_target.zig"
534534 "${CMAKE_SOURCE_DIR}/lib/std/zig/parse.zig"
535535 "${CMAKE_SOURCE_DIR}/lib/std/zig/render.zig"
lib/std/zig.zig+1-1
......@@ -10,7 +10,7 @@ pub const fmtEscapes = fmt.fmtEscapes;
1010pub const isValidId = fmt.isValidId;
1111pub const parse = @import("zig/parse.zig").parse;
1212pub const string_literal = @import("zig/string_literal.zig");
13pub const ast = @import("zig/ast.zig");
13pub const Ast = @import("zig/Ast.zig");
1414pub const system = @import("zig/system.zig");
1515pub const CrossTarget = @import("zig/cross_target.zig").CrossTarget;
1616
lib/std/zig/Ast.zig created+2979
......@@ -0,0 +1,2979 @@
1//! Abstract Syntax Tree for Zig source code.
2
3/// Reference to externally-owned data.
4source: [:0]const u8,
5
6tokens: TokenList.Slice,
7/// The root AST node is assumed to be index 0. Since there can be no
8/// references to the root node, this means 0 is available to indicate null.
9nodes: NodeList.Slice,
10extra_data: []Node.Index,
11
12errors: []const Error,
13
14const std = @import("../std.zig");
15const assert = std.debug.assert;
16const testing = std.testing;
17const mem = std.mem;
18const Token = std.zig.Token;
19const Tree = @This();
20
21pub const TokenIndex = u32;
22pub const ByteOffset = u32;
23
24pub const TokenList = std.MultiArrayList(struct {
25 tag: Token.Tag,
26 start: ByteOffset,
27});
28pub const NodeList = std.MultiArrayList(Node);
29
30pub const Location = struct {
31 line: usize,
32 column: usize,
33 line_start: usize,
34 line_end: usize,
35};
36
37pub fn deinit(tree: *Tree, gpa: *mem.Allocator) void {
38 tree.tokens.deinit(gpa);
39 tree.nodes.deinit(gpa);
40 gpa.free(tree.extra_data);
41 gpa.free(tree.errors);
42 tree.* = undefined;
43}
44
45pub const RenderError = error{
46 /// Ran out of memory allocating call stack frames to complete rendering, or
47 /// ran out of memory allocating space in the output buffer.
48 OutOfMemory,
49};
50
51/// `gpa` is used for allocating the resulting formatted source code, as well as
52/// for allocating extra stack memory if needed, because this function utilizes recursion.
53/// Note: that's not actually true yet, see https://github.com/ziglang/zig/issues/1006.
54/// Caller owns the returned slice of bytes, allocated with `gpa`.
55pub fn render(tree: Tree, gpa: *mem.Allocator) RenderError![]u8 {
56 var buffer = std.ArrayList(u8).init(gpa);
57 defer buffer.deinit();
58
59 try tree.renderToArrayList(&buffer);
60 return buffer.toOwnedSlice();
61}
62
63pub fn renderToArrayList(tree: Tree, buffer: *std.ArrayList(u8)) RenderError!void {
64 return @import("./render.zig").renderTree(buffer, tree);
65}
66
67pub fn tokenLocation(self: Tree, start_offset: ByteOffset, token_index: TokenIndex) Location {
68 var loc = Location{
69 .line = 0,
70 .column = 0,
71 .line_start = start_offset,
72 .line_end = self.source.len,
73 };
74 const token_start = self.tokens.items(.start)[token_index];
75 for (self.source[start_offset..]) |c, i| {
76 if (i + start_offset == token_start) {
77 loc.line_end = i + start_offset;
78 while (loc.line_end < self.source.len and self.source[loc.line_end] != '\n') {
79 loc.line_end += 1;
80 }
81 return loc;
82 }
83 if (c == '\n') {
84 loc.line += 1;
85 loc.column = 0;
86 loc.line_start = i + 1;
87 } else {
88 loc.column += 1;
89 }
90 }
91 return loc;
92}
93
94pub fn tokenSlice(tree: Tree, token_index: TokenIndex) []const u8 {
95 const token_starts = tree.tokens.items(.start);
96 const token_tags = tree.tokens.items(.tag);
97 const token_tag = token_tags[token_index];
98
99 // Many tokens can be determined entirely by their tag.
100 if (token_tag.lexeme()) |lexeme| {
101 return lexeme;
102 }
103
104 // For some tokens, re-tokenization is needed to find the end.
105 var tokenizer: std.zig.Tokenizer = .{
106 .buffer = tree.source,
107 .index = token_starts[token_index],
108 .pending_invalid_token = null,
109 };
110 const token = tokenizer.next();
111 assert(token.tag == token_tag);
112 return tree.source[token.loc.start..token.loc.end];
113}
114
115pub fn extraData(tree: Tree, index: usize, comptime T: type) T {
116 const fields = std.meta.fields(T);
117 var result: T = undefined;
118 inline for (fields) |field, i| {
119 comptime assert(field.field_type == Node.Index);
120 @field(result, field.name) = tree.extra_data[index + i];
121 }
122 return result;
123}
124
125pub fn rootDecls(tree: Tree) []const Node.Index {
126 // Root is always index 0.
127 const nodes_data = tree.nodes.items(.data);
128 return tree.extra_data[nodes_data[0].lhs..nodes_data[0].rhs];
129}
130
131pub fn renderError(tree: Tree, parse_error: Error, stream: anytype) !void {
132 const token_tags = tree.tokens.items(.tag);
133 switch (parse_error.tag) {
134 .asterisk_after_ptr_deref => {
135 // Note that the token will point at the `.*` but ideally the source
136 // location would point to the `*` after the `.*`.
137 return stream.writeAll("'.*' cannot be followed by '*'. Are you missing a space?");
138 },
139 .decl_between_fields => {
140 return stream.writeAll("declarations are not allowed between container fields");
141 },
142 .expected_block => {
143 return stream.print("expected block or field, found '{s}'", .{
144 token_tags[parse_error.token].symbol(),
145 });
146 },
147 .expected_block_or_assignment => {
148 return stream.print("expected block or assignment, found '{s}'", .{
149 token_tags[parse_error.token].symbol(),
150 });
151 },
152 .expected_block_or_expr => {
153 return stream.print("expected block or expression, found '{s}'", .{
154 token_tags[parse_error.token].symbol(),
155 });
156 },
157 .expected_block_or_field => {
158 return stream.print("expected block or field, found '{s}'", .{
159 token_tags[parse_error.token].symbol(),
160 });
161 },
162 .expected_container_members => {
163 return stream.print("expected test, comptime, var decl, or container field, found '{s}'", .{
164 token_tags[parse_error.token].symbol(),
165 });
166 },
167 .expected_expr => {
168 return stream.print("expected expression, found '{s}'", .{
169 token_tags[parse_error.token].symbol(),
170 });
171 },
172 .expected_expr_or_assignment => {
173 return stream.print("expected expression or assignment, found '{s}'", .{
174 token_tags[parse_error.token].symbol(),
175 });
176 },
177 .expected_fn => {
178 return stream.print("expected function, found '{s}'", .{
179 token_tags[parse_error.token].symbol(),
180 });
181 },
182 .expected_inlinable => {
183 return stream.print("expected 'while' or 'for', found '{s}'", .{
184 token_tags[parse_error.token].symbol(),
185 });
186 },
187 .expected_labelable => {
188 return stream.print("expected 'while', 'for', 'inline', 'suspend', or '{{', found '{s}'", .{
189 token_tags[parse_error.token].symbol(),
190 });
191 },
192 .expected_param_list => {
193 return stream.print("expected parameter list, found '{s}'", .{
194 token_tags[parse_error.token].symbol(),
195 });
196 },
197 .expected_prefix_expr => {
198 return stream.print("expected prefix expression, found '{s}'", .{
199 token_tags[parse_error.token].symbol(),
200 });
201 },
202 .expected_primary_type_expr => {
203 return stream.print("expected primary type expression, found '{s}'", .{
204 token_tags[parse_error.token].symbol(),
205 });
206 },
207 .expected_pub_item => {
208 return stream.writeAll("expected function or variable declaration after pub");
209 },
210 .expected_return_type => {
211 return stream.print("expected return type expression, found '{s}'", .{
212 token_tags[parse_error.token].symbol(),
213 });
214 },
215 .expected_semi_or_else => {
216 return stream.print("expected ';' or 'else', found '{s}'", .{
217 token_tags[parse_error.token].symbol(),
218 });
219 },
220 .expected_semi_or_lbrace => {
221 return stream.print("expected ';' or '{{', found '{s}'", .{
222 token_tags[parse_error.token].symbol(),
223 });
224 },
225 .expected_statement => {
226 return stream.print("expected statement, found '{s}'", .{
227 token_tags[parse_error.token].symbol(),
228 });
229 },
230 .expected_string_literal => {
231 return stream.print("expected string literal, found '{s}'", .{
232 token_tags[parse_error.token].symbol(),
233 });
234 },
235 .expected_suffix_op => {
236 return stream.print("expected pointer dereference, optional unwrap, or field access, found '{s}'", .{
237 token_tags[parse_error.token].symbol(),
238 });
239 },
240 .expected_type_expr => {
241 return stream.print("expected type expression, found '{s}'", .{
242 token_tags[parse_error.token].symbol(),
243 });
244 },
245 .expected_var_decl => {
246 return stream.print("expected variable declaration, found '{s}'", .{
247 token_tags[parse_error.token].symbol(),
248 });
249 },
250 .expected_var_decl_or_fn => {
251 return stream.print("expected variable declaration or function, found '{s}'", .{
252 token_tags[parse_error.token].symbol(),
253 });
254 },
255 .expected_loop_payload => {
256 return stream.print("expected loop payload, found '{s}'", .{
257 token_tags[parse_error.token].symbol(),
258 });
259 },
260 .expected_container => {
261 return stream.print("expected a struct, enum or union, found '{s}'", .{
262 token_tags[parse_error.token].symbol(),
263 });
264 },
265 .extra_align_qualifier => {
266 return stream.writeAll("extra align qualifier");
267 },
268 .extra_allowzero_qualifier => {
269 return stream.writeAll("extra allowzero qualifier");
270 },
271 .extra_const_qualifier => {
272 return stream.writeAll("extra const qualifier");
273 },
274 .extra_volatile_qualifier => {
275 return stream.writeAll("extra volatile qualifier");
276 },
277 .ptr_mod_on_array_child_type => {
278 return stream.print("pointer modifier '{s}' not allowed on array child type", .{
279 token_tags[parse_error.token].symbol(),
280 });
281 },
282 .invalid_bit_range => {
283 return stream.writeAll("bit range not allowed on slices and arrays");
284 },
285 .invalid_token => {
286 return stream.print("invalid token: '{s}'", .{
287 token_tags[parse_error.token].symbol(),
288 });
289 },
290 .same_line_doc_comment => {
291 return stream.writeAll("same line documentation comment");
292 },
293 .unattached_doc_comment => {
294 return stream.writeAll("unattached documentation comment");
295 },
296 .varargs_nonfinal => {
297 return stream.writeAll("function prototype has parameter after varargs");
298 },
299
300 .expected_token => {
301 const found_tag = token_tags[parse_error.token];
302 const expected_symbol = parse_error.extra.expected_tag.symbol();
303 switch (found_tag) {
304 .invalid => return stream.print("expected '{s}', found invalid bytes", .{
305 expected_symbol,
306 }),
307 else => return stream.print("expected '{s}', found '{s}'", .{
308 expected_symbol, found_tag.symbol(),
309 }),
310 }
311 },
312 }
313}
314
315pub fn firstToken(tree: Tree, node: Node.Index) TokenIndex {
316 const tags = tree.nodes.items(.tag);
317 const datas = tree.nodes.items(.data);
318 const main_tokens = tree.nodes.items(.main_token);
319 const token_tags = tree.tokens.items(.tag);
320 var end_offset: TokenIndex = 0;
321 var n = node;
322 while (true) switch (tags[n]) {
323 .root => return 0,
324
325 .test_decl,
326 .@"errdefer",
327 .@"defer",
328 .bool_not,
329 .negation,
330 .bit_not,
331 .negation_wrap,
332 .address_of,
333 .@"try",
334 .@"await",
335 .optional_type,
336 .@"switch",
337 .switch_comma,
338 .if_simple,
339 .@"if",
340 .@"suspend",
341 .@"resume",
342 .@"continue",
343 .@"break",
344 .@"return",
345 .anyframe_type,
346 .identifier,
347 .anyframe_literal,
348 .char_literal,
349 .integer_literal,
350 .float_literal,
351 .unreachable_literal,
352 .string_literal,
353 .multiline_string_literal,
354 .grouped_expression,
355 .builtin_call_two,
356 .builtin_call_two_comma,
357 .builtin_call,
358 .builtin_call_comma,
359 .error_set_decl,
360 .@"anytype",
361 .@"comptime",
362 .@"nosuspend",
363 .asm_simple,
364 .@"asm",
365 .array_type,
366 .array_type_sentinel,
367 .error_value,
368 => return main_tokens[n] - end_offset,
369
370 .array_init_dot,
371 .array_init_dot_comma,
372 .array_init_dot_two,
373 .array_init_dot_two_comma,
374 .struct_init_dot,
375 .struct_init_dot_comma,
376 .struct_init_dot_two,
377 .struct_init_dot_two_comma,
378 .enum_literal,
379 => return main_tokens[n] - 1 - end_offset,
380
381 .@"catch",
382 .field_access,
383 .unwrap_optional,
384 .equal_equal,
385 .bang_equal,
386 .less_than,
387 .greater_than,
388 .less_or_equal,
389 .greater_or_equal,
390 .assign_mul,
391 .assign_div,
392 .assign_mod,
393 .assign_add,
394 .assign_sub,
395 .assign_bit_shift_left,
396 .assign_bit_shift_right,
397 .assign_bit_and,
398 .assign_bit_xor,
399 .assign_bit_or,
400 .assign_mul_wrap,
401 .assign_add_wrap,
402 .assign_sub_wrap,
403 .assign,
404 .merge_error_sets,
405 .mul,
406 .div,
407 .mod,
408 .array_mult,
409 .mul_wrap,
410 .add,
411 .sub,
412 .array_cat,
413 .add_wrap,
414 .sub_wrap,
415 .bit_shift_left,
416 .bit_shift_right,
417 .bit_and,
418 .bit_xor,
419 .bit_or,
420 .@"orelse",
421 .bool_and,
422 .bool_or,
423 .slice_open,
424 .slice,
425 .slice_sentinel,
426 .deref,
427 .array_access,
428 .array_init_one,
429 .array_init_one_comma,
430 .array_init,
431 .array_init_comma,
432 .struct_init_one,
433 .struct_init_one_comma,
434 .struct_init,
435 .struct_init_comma,
436 .call_one,
437 .call_one_comma,
438 .call,
439 .call_comma,
440 .switch_range,
441 .error_union,
442 => n = datas[n].lhs,
443
444 .fn_decl,
445 .fn_proto_simple,
446 .fn_proto_multi,
447 .fn_proto_one,
448 .fn_proto,
449 => {
450 var i = main_tokens[n]; // fn token
451 while (i > 0) {
452 i -= 1;
453 switch (token_tags[i]) {
454 .keyword_extern,
455 .keyword_export,
456 .keyword_pub,
457 .keyword_inline,
458 .keyword_noinline,
459 .string_literal,
460 => continue,
461
462 else => return i + 1 - end_offset,
463 }
464 }
465 return i - end_offset;
466 },
467
468 .@"usingnamespace" => {
469 const main_token = main_tokens[n];
470 if (main_token > 0 and token_tags[main_token - 1] == .keyword_pub) {
471 end_offset += 1;
472 }
473 return main_token - end_offset;
474 },
475
476 .async_call_one,
477 .async_call_one_comma,
478 .async_call,
479 .async_call_comma,
480 => {
481 end_offset += 1; // async token
482 n = datas[n].lhs;
483 },
484
485 .container_field_init,
486 .container_field_align,
487 .container_field,
488 => {
489 const name_token = main_tokens[n];
490 if (name_token > 0 and token_tags[name_token - 1] == .keyword_comptime) {
491 end_offset += 1;
492 }
493 return name_token - end_offset;
494 },
495
496 .global_var_decl,
497 .local_var_decl,
498 .simple_var_decl,
499 .aligned_var_decl,
500 => {
501 var i = main_tokens[n]; // mut token
502 while (i > 0) {
503 i -= 1;
504 switch (token_tags[i]) {
505 .keyword_extern,
506 .keyword_export,
507 .keyword_comptime,
508 .keyword_pub,
509 .keyword_threadlocal,
510 .string_literal,
511 => continue,
512
513 else => return i + 1 - end_offset,
514 }
515 }
516 return i - end_offset;
517 },
518
519 .block,
520 .block_semicolon,
521 .block_two,
522 .block_two_semicolon,
523 => {
524 // Look for a label.
525 const lbrace = main_tokens[n];
526 if (token_tags[lbrace - 1] == .colon and
527 token_tags[lbrace - 2] == .identifier)
528 {
529 end_offset += 2;
530 }
531 return lbrace - end_offset;
532 },
533
534 .container_decl,
535 .container_decl_trailing,
536 .container_decl_two,
537 .container_decl_two_trailing,
538 .container_decl_arg,
539 .container_decl_arg_trailing,
540 .tagged_union,
541 .tagged_union_trailing,
542 .tagged_union_two,
543 .tagged_union_two_trailing,
544 .tagged_union_enum_tag,
545 .tagged_union_enum_tag_trailing,
546 => {
547 const main_token = main_tokens[n];
548 switch (token_tags[main_token - 1]) {
549 .keyword_packed, .keyword_extern => end_offset += 1,
550 else => {},
551 }
552 return main_token - end_offset;
553 },
554
555 .ptr_type_aligned,
556 .ptr_type_sentinel,
557 .ptr_type,
558 .ptr_type_bit_range,
559 => {
560 const main_token = main_tokens[n];
561 return switch (token_tags[main_token]) {
562 .asterisk,
563 .asterisk_asterisk,
564 => switch (token_tags[main_token - 1]) {
565 .l_bracket => main_token - 1,
566 else => main_token,
567 },
568 .l_bracket => main_token,
569 else => unreachable,
570 } - end_offset;
571 },
572
573 .switch_case_one => {
574 if (datas[n].lhs == 0) {
575 return main_tokens[n] - 1 - end_offset; // else token
576 } else {
577 n = datas[n].lhs;
578 }
579 },
580 .switch_case => {
581 const extra = tree.extraData(datas[n].lhs, Node.SubRange);
582 assert(extra.end - extra.start > 0);
583 n = tree.extra_data[extra.start];
584 },
585
586 .asm_output, .asm_input => {
587 assert(token_tags[main_tokens[n] - 1] == .l_bracket);
588 return main_tokens[n] - 1 - end_offset;
589 },
590
591 .while_simple,
592 .while_cont,
593 .@"while",
594 .for_simple,
595 .@"for",
596 => {
597 // Look for a label and inline.
598 const main_token = main_tokens[n];
599 var result = main_token;
600 if (token_tags[result - 1] == .keyword_inline) {
601 result -= 1;
602 }
603 if (token_tags[result - 1] == .colon) {
604 result -= 2;
605 }
606 return result - end_offset;
607 },
608 };
609}
610
611pub fn lastToken(tree: Tree, node: Node.Index) TokenIndex {
612 const tags = tree.nodes.items(.tag);
613 const datas = tree.nodes.items(.data);
614 const main_tokens = tree.nodes.items(.main_token);
615 const token_starts = tree.tokens.items(.start);
616 const token_tags = tree.tokens.items(.tag);
617 var n = node;
618 var end_offset: TokenIndex = 0;
619 while (true) switch (tags[n]) {
620 .root => return @intCast(TokenIndex, tree.tokens.len - 1),
621
622 .@"usingnamespace",
623 .bool_not,
624 .negation,
625 .bit_not,
626 .negation_wrap,
627 .address_of,
628 .@"try",
629 .@"await",
630 .optional_type,
631 .@"resume",
632 .@"nosuspend",
633 .@"comptime",
634 => n = datas[n].lhs,
635
636 .test_decl,
637 .@"errdefer",
638 .@"defer",
639 .@"catch",
640 .equal_equal,
641 .bang_equal,
642 .less_than,
643 .greater_than,
644 .less_or_equal,
645 .greater_or_equal,
646 .assign_mul,
647 .assign_div,
648 .assign_mod,
649 .assign_add,
650 .assign_sub,
651 .assign_bit_shift_left,
652 .assign_bit_shift_right,
653 .assign_bit_and,
654 .assign_bit_xor,
655 .assign_bit_or,
656 .assign_mul_wrap,
657 .assign_add_wrap,
658 .assign_sub_wrap,
659 .assign,
660 .merge_error_sets,
661 .mul,
662 .div,
663 .mod,
664 .array_mult,
665 .mul_wrap,
666 .add,
667 .sub,
668 .array_cat,
669 .add_wrap,
670 .sub_wrap,
671 .bit_shift_left,
672 .bit_shift_right,
673 .bit_and,
674 .bit_xor,
675 .bit_or,
676 .@"orelse",
677 .bool_and,
678 .bool_or,
679 .anyframe_type,
680 .error_union,
681 .if_simple,
682 .while_simple,
683 .for_simple,
684 .fn_proto_simple,
685 .fn_proto_multi,
686 .ptr_type_aligned,
687 .ptr_type_sentinel,
688 .ptr_type,
689 .ptr_type_bit_range,
690 .array_type,
691 .switch_case_one,
692 .switch_case,
693 .switch_range,
694 => n = datas[n].rhs,
695
696 .field_access,
697 .unwrap_optional,
698 .grouped_expression,
699 .multiline_string_literal,
700 .error_set_decl,
701 .asm_simple,
702 .asm_output,
703 .asm_input,
704 .error_value,
705 => return datas[n].rhs + end_offset,
706
707 .@"anytype",
708 .anyframe_literal,
709 .char_literal,
710 .integer_literal,
711 .float_literal,
712 .unreachable_literal,
713 .identifier,
714 .deref,
715 .enum_literal,
716 .string_literal,
717 => return main_tokens[n] + end_offset,
718
719 .@"return" => if (datas[n].lhs != 0) {
720 n = datas[n].lhs;
721 } else {
722 return main_tokens[n] + end_offset;
723 },
724
725 .call, .async_call => {
726 end_offset += 1; // for the rparen
727 const params = tree.extraData(datas[n].rhs, Node.SubRange);
728 if (params.end - params.start == 0) {
729 return main_tokens[n] + end_offset;
730 }
731 n = tree.extra_data[params.end - 1]; // last parameter
732 },
733 .tagged_union_enum_tag => {
734 const members = tree.extraData(datas[n].rhs, Node.SubRange);
735 if (members.end - members.start == 0) {
736 end_offset += 4; // for the rparen + rparen + lbrace + rbrace
737 n = datas[n].lhs;
738 } else {
739 end_offset += 1; // for the rbrace
740 n = tree.extra_data[members.end - 1]; // last parameter
741 }
742 },
743 .call_comma,
744 .async_call_comma,
745 .tagged_union_enum_tag_trailing,
746 => {
747 end_offset += 2; // for the comma/semicolon + rparen/rbrace
748 const params = tree.extraData(datas[n].rhs, Node.SubRange);
749 assert(params.end > params.start);
750 n = tree.extra_data[params.end - 1]; // last parameter
751 },
752 .@"switch" => {
753 const cases = tree.extraData(datas[n].rhs, Node.SubRange);
754 if (cases.end - cases.start == 0) {
755 end_offset += 3; // rparen, lbrace, rbrace
756 n = datas[n].lhs; // condition expression
757 } else {
758 end_offset += 1; // for the rbrace
759 n = tree.extra_data[cases.end - 1]; // last case
760 }
761 },
762 .container_decl_arg => {
763 const members = tree.extraData(datas[n].rhs, Node.SubRange);
764 if (members.end - members.start == 0) {
765 end_offset += 3; // for the rparen + lbrace + rbrace
766 n = datas[n].lhs;
767 } else {
768 end_offset += 1; // for the rbrace
769 n = tree.extra_data[members.end - 1]; // last parameter
770 }
771 },
772 .@"asm" => {
773 const extra = tree.extraData(datas[n].rhs, Node.Asm);
774 return extra.rparen + end_offset;
775 },
776 .array_init,
777 .struct_init,
778 => {
779 const elements = tree.extraData(datas[n].rhs, Node.SubRange);
780 assert(elements.end - elements.start > 0);
781 end_offset += 1; // for the rbrace
782 n = tree.extra_data[elements.end - 1]; // last element
783 },
784 .array_init_comma,
785 .struct_init_comma,
786 .container_decl_arg_trailing,
787 .switch_comma,
788 => {
789 const members = tree.extraData(datas[n].rhs, Node.SubRange);
790 assert(members.end - members.start > 0);
791 end_offset += 2; // for the comma + rbrace
792 n = tree.extra_data[members.end - 1]; // last parameter
793 },
794 .array_init_dot,
795 .struct_init_dot,
796 .block,
797 .container_decl,
798 .tagged_union,
799 .builtin_call,
800 => {
801 assert(datas[n].rhs - datas[n].lhs > 0);
802 end_offset += 1; // for the rbrace
803 n = tree.extra_data[datas[n].rhs - 1]; // last statement
804 },
805 .array_init_dot_comma,
806 .struct_init_dot_comma,
807 .block_semicolon,
808 .container_decl_trailing,
809 .tagged_union_trailing,
810 .builtin_call_comma,
811 => {
812 assert(datas[n].rhs - datas[n].lhs > 0);
813 end_offset += 2; // for the comma/semicolon + rbrace/rparen
814 n = tree.extra_data[datas[n].rhs - 1]; // last member
815 },
816 .call_one,
817 .async_call_one,
818 .array_access,
819 => {
820 end_offset += 1; // for the rparen/rbracket
821 if (datas[n].rhs == 0) {
822 return main_tokens[n] + end_offset;
823 }
824 n = datas[n].rhs;
825 },
826 .array_init_dot_two,
827 .block_two,
828 .builtin_call_two,
829 .struct_init_dot_two,
830 .container_decl_two,
831 .tagged_union_two,
832 => {
833 if (datas[n].rhs != 0) {
834 end_offset += 1; // for the rparen/rbrace
835 n = datas[n].rhs;
836 } else if (datas[n].lhs != 0) {
837 end_offset += 1; // for the rparen/rbrace
838 n = datas[n].lhs;
839 } else {
840 switch (tags[n]) {
841 .array_init_dot_two,
842 .block_two,
843 .struct_init_dot_two,
844 => end_offset += 1, // rbrace
845 .builtin_call_two => end_offset += 2, // lparen/lbrace + rparen/rbrace
846 .container_decl_two => {
847 var i: u32 = 2; // lbrace + rbrace
848 while (token_tags[main_tokens[n] + i] == .container_doc_comment) i += 1;
849 end_offset += i;
850 },
851 .tagged_union_two => {
852 var i: u32 = 5; // (enum) {}
853 while (token_tags[main_tokens[n] + i] == .container_doc_comment) i += 1;
854 end_offset += i;
855 },
856 else => unreachable,
857 }
858 return main_tokens[n] + end_offset;
859 }
860 },
861 .array_init_dot_two_comma,
862 .builtin_call_two_comma,
863 .block_two_semicolon,
864 .struct_init_dot_two_comma,
865 .container_decl_two_trailing,
866 .tagged_union_two_trailing,
867 => {
868 end_offset += 2; // for the comma/semicolon + rbrace/rparen
869 if (datas[n].rhs != 0) {
870 n = datas[n].rhs;
871 } else if (datas[n].lhs != 0) {
872 n = datas[n].lhs;
873 } else {
874 unreachable;
875 }
876 },
877 .simple_var_decl => {
878 if (datas[n].rhs != 0) {
879 n = datas[n].rhs;
880 } else if (datas[n].lhs != 0) {
881 n = datas[n].lhs;
882 } else {
883 end_offset += 1; // from mut token to name
884 return main_tokens[n] + end_offset;
885 }
886 },
887 .aligned_var_decl => {
888 if (datas[n].rhs != 0) {
889 n = datas[n].rhs;
890 } else if (datas[n].lhs != 0) {
891 end_offset += 1; // for the rparen
892 n = datas[n].lhs;
893 } else {
894 end_offset += 1; // from mut token to name
895 return main_tokens[n] + end_offset;
896 }
897 },
898 .global_var_decl => {
899 if (datas[n].rhs != 0) {
900 n = datas[n].rhs;
901 } else {
902 const extra = tree.extraData(datas[n].lhs, Node.GlobalVarDecl);
903 if (extra.section_node != 0) {
904 end_offset += 1; // for the rparen
905 n = extra.section_node;
906 } else if (extra.align_node != 0) {
907 end_offset += 1; // for the rparen
908 n = extra.align_node;
909 } else if (extra.type_node != 0) {
910 n = extra.type_node;
911 } else {
912 end_offset += 1; // from mut token to name
913 return main_tokens[n] + end_offset;
914 }
915 }
916 },
917 .local_var_decl => {
918 if (datas[n].rhs != 0) {
919 n = datas[n].rhs;
920 } else {
921 const extra = tree.extraData(datas[n].lhs, Node.LocalVarDecl);
922 if (extra.align_node != 0) {
923 end_offset += 1; // for the rparen
924 n = extra.align_node;
925 } else if (extra.type_node != 0) {
926 n = extra.type_node;
927 } else {
928 end_offset += 1; // from mut token to name
929 return main_tokens[n] + end_offset;
930 }
931 }
932 },
933 .container_field_init => {
934 if (datas[n].rhs != 0) {
935 n = datas[n].rhs;
936 } else if (datas[n].lhs != 0) {
937 n = datas[n].lhs;
938 } else {
939 return main_tokens[n] + end_offset;
940 }
941 },
942 .container_field_align => {
943 if (datas[n].rhs != 0) {
944 end_offset += 1; // for the rparen
945 n = datas[n].rhs;
946 } else if (datas[n].lhs != 0) {
947 n = datas[n].lhs;
948 } else {
949 return main_tokens[n] + end_offset;
950 }
951 },
952 .container_field => {
953 const extra = tree.extraData(datas[n].rhs, Node.ContainerField);
954 if (extra.value_expr != 0) {
955 n = extra.value_expr;
956 } else if (extra.align_expr != 0) {
957 end_offset += 1; // for the rparen
958 n = extra.align_expr;
959 } else if (datas[n].lhs != 0) {
960 n = datas[n].lhs;
961 } else {
962 return main_tokens[n] + end_offset;
963 }
964 },
965
966 .array_init_one,
967 .struct_init_one,
968 => {
969 end_offset += 1; // rbrace
970 if (datas[n].rhs == 0) {
971 return main_tokens[n] + end_offset;
972 } else {
973 n = datas[n].rhs;
974 }
975 },
976 .slice_open,
977 .call_one_comma,
978 .async_call_one_comma,
979 .array_init_one_comma,
980 .struct_init_one_comma,
981 => {
982 end_offset += 2; // ellipsis2 + rbracket, or comma + rparen
983 n = datas[n].rhs;
984 assert(n != 0);
985 },
986 .slice => {
987 const extra = tree.extraData(datas[n].rhs, Node.Slice);
988 assert(extra.end != 0); // should have used slice_open
989 end_offset += 1; // rbracket
990 n = extra.end;
991 },
992 .slice_sentinel => {
993 const extra = tree.extraData(datas[n].rhs, Node.SliceSentinel);
994 assert(extra.sentinel != 0); // should have used slice
995 end_offset += 1; // rbracket
996 n = extra.sentinel;
997 },
998
999 .@"continue" => {
1000 if (datas[n].lhs != 0) {
1001 return datas[n].lhs + end_offset;
1002 } else {
1003 return main_tokens[n] + end_offset;
1004 }
1005 },
1006 .@"break" => {
1007 if (datas[n].rhs != 0) {
1008 n = datas[n].rhs;
1009 } else if (datas[n].lhs != 0) {
1010 return datas[n].lhs + end_offset;
1011 } else {
1012 return main_tokens[n] + end_offset;
1013 }
1014 },
1015 .fn_decl => {
1016 if (datas[n].rhs != 0) {
1017 n = datas[n].rhs;
1018 } else {
1019 n = datas[n].lhs;
1020 }
1021 },
1022 .fn_proto_one => {
1023 const extra = tree.extraData(datas[n].lhs, Node.FnProtoOne);
1024 // linksection, callconv, align can appear in any order, so we
1025 // find the last one here.
1026 var max_node: Node.Index = datas[n].rhs;
1027 var max_start = token_starts[main_tokens[max_node]];
1028 var max_offset: TokenIndex = 0;
1029 if (extra.align_expr != 0) {
1030 const start = token_starts[main_tokens[extra.align_expr]];
1031 if (start > max_start) {
1032 max_node = extra.align_expr;
1033 max_start = start;
1034 max_offset = 1; // for the rparen
1035 }
1036 }
1037 if (extra.section_expr != 0) {
1038 const start = token_starts[main_tokens[extra.section_expr]];
1039 if (start > max_start) {
1040 max_node = extra.section_expr;
1041 max_start = start;
1042 max_offset = 1; // for the rparen
1043 }
1044 }
1045 if (extra.callconv_expr != 0) {
1046 const start = token_starts[main_tokens[extra.callconv_expr]];
1047 if (start > max_start) {
1048 max_node = extra.callconv_expr;
1049 max_start = start;
1050 max_offset = 1; // for the rparen
1051 }
1052 }
1053 n = max_node;
1054 end_offset += max_offset;
1055 },
1056 .fn_proto => {
1057 const extra = tree.extraData(datas[n].lhs, Node.FnProto);
1058 // linksection, callconv, align can appear in any order, so we
1059 // find the last one here.
1060 var max_node: Node.Index = datas[n].rhs;
1061 var max_start = token_starts[main_tokens[max_node]];
1062 var max_offset: TokenIndex = 0;
1063 if (extra.align_expr != 0) {
1064 const start = token_starts[main_tokens[extra.align_expr]];
1065 if (start > max_start) {
1066 max_node = extra.align_expr;
1067 max_start = start;
1068 max_offset = 1; // for the rparen
1069 }
1070 }
1071 if (extra.section_expr != 0) {
1072 const start = token_starts[main_tokens[extra.section_expr]];
1073 if (start > max_start) {
1074 max_node = extra.section_expr;
1075 max_start = start;
1076 max_offset = 1; // for the rparen
1077 }
1078 }
1079 if (extra.callconv_expr != 0) {
1080 const start = token_starts[main_tokens[extra.callconv_expr]];
1081 if (start > max_start) {
1082 max_node = extra.callconv_expr;
1083 max_start = start;
1084 max_offset = 1; // for the rparen
1085 }
1086 }
1087 n = max_node;
1088 end_offset += max_offset;
1089 },
1090 .while_cont => {
1091 const extra = tree.extraData(datas[n].rhs, Node.WhileCont);
1092 assert(extra.then_expr != 0);
1093 n = extra.then_expr;
1094 },
1095 .@"while" => {
1096 const extra = tree.extraData(datas[n].rhs, Node.While);
1097 assert(extra.else_expr != 0);
1098 n = extra.else_expr;
1099 },
1100 .@"if", .@"for" => {
1101 const extra = tree.extraData(datas[n].rhs, Node.If);
1102 assert(extra.else_expr != 0);
1103 n = extra.else_expr;
1104 },
1105 .@"suspend" => {
1106 if (datas[n].lhs != 0) {
1107 n = datas[n].lhs;
1108 } else {
1109 return main_tokens[n] + end_offset;
1110 }
1111 },
1112 .array_type_sentinel => {
1113 const extra = tree.extraData(datas[n].rhs, Node.ArrayTypeSentinel);
1114 n = extra.elem_type;
1115 },
1116 };
1117}
1118
1119pub fn tokensOnSameLine(tree: Tree, token1: TokenIndex, token2: TokenIndex) bool {
1120 const token_starts = tree.tokens.items(.start);
1121 const source = tree.source[token_starts[token1]..token_starts[token2]];
1122 return mem.indexOfScalar(u8, source, '\n') == null;
1123}
1124
1125pub fn getNodeSource(tree: Tree, node: Node.Index) []const u8 {
1126 const token_starts = tree.tokens.items(.start);
1127 const first_token = tree.firstToken(node);
1128 const last_token = tree.lastToken(node);
1129 const start = token_starts[first_token];
1130 const end = token_starts[last_token] + tree.tokenSlice(last_token).len;
1131 return tree.source[start..end];
1132}
1133
1134pub fn globalVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
1135 assert(tree.nodes.items(.tag)[node] == .global_var_decl);
1136 const data = tree.nodes.items(.data)[node];
1137 const extra = tree.extraData(data.lhs, Node.GlobalVarDecl);
1138 return tree.fullVarDecl(.{
1139 .type_node = extra.type_node,
1140 .align_node = extra.align_node,
1141 .section_node = extra.section_node,
1142 .init_node = data.rhs,
1143 .mut_token = tree.nodes.items(.main_token)[node],
1144 });
1145}
1146
1147pub fn localVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
1148 assert(tree.nodes.items(.tag)[node] == .local_var_decl);
1149 const data = tree.nodes.items(.data)[node];
1150 const extra = tree.extraData(data.lhs, Node.LocalVarDecl);
1151 return tree.fullVarDecl(.{
1152 .type_node = extra.type_node,
1153 .align_node = extra.align_node,
1154 .section_node = 0,
1155 .init_node = data.rhs,
1156 .mut_token = tree.nodes.items(.main_token)[node],
1157 });
1158}
1159
1160pub fn simpleVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
1161 assert(tree.nodes.items(.tag)[node] == .simple_var_decl);
1162 const data = tree.nodes.items(.data)[node];
1163 return tree.fullVarDecl(.{
1164 .type_node = data.lhs,
1165 .align_node = 0,
1166 .section_node = 0,
1167 .init_node = data.rhs,
1168 .mut_token = tree.nodes.items(.main_token)[node],
1169 });
1170}
1171
1172pub fn alignedVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
1173 assert(tree.nodes.items(.tag)[node] == .aligned_var_decl);
1174 const data = tree.nodes.items(.data)[node];
1175 return tree.fullVarDecl(.{
1176 .type_node = 0,
1177 .align_node = data.lhs,
1178 .section_node = 0,
1179 .init_node = data.rhs,
1180 .mut_token = tree.nodes.items(.main_token)[node],
1181 });
1182}
1183
1184pub fn ifSimple(tree: Tree, node: Node.Index) full.If {
1185 assert(tree.nodes.items(.tag)[node] == .if_simple);
1186 const data = tree.nodes.items(.data)[node];
1187 return tree.fullIf(.{
1188 .cond_expr = data.lhs,
1189 .then_expr = data.rhs,
1190 .else_expr = 0,
1191 .if_token = tree.nodes.items(.main_token)[node],
1192 });
1193}
1194
1195pub fn ifFull(tree: Tree, node: Node.Index) full.If {
1196 assert(tree.nodes.items(.tag)[node] == .@"if");
1197 const data = tree.nodes.items(.data)[node];
1198 const extra = tree.extraData(data.rhs, Node.If);
1199 return tree.fullIf(.{
1200 .cond_expr = data.lhs,
1201 .then_expr = extra.then_expr,
1202 .else_expr = extra.else_expr,
1203 .if_token = tree.nodes.items(.main_token)[node],
1204 });
1205}
1206
1207pub fn containerField(tree: Tree, node: Node.Index) full.ContainerField {
1208 assert(tree.nodes.items(.tag)[node] == .container_field);
1209 const data = tree.nodes.items(.data)[node];
1210 const extra = tree.extraData(data.rhs, Node.ContainerField);
1211 return tree.fullContainerField(.{
1212 .name_token = tree.nodes.items(.main_token)[node],
1213 .type_expr = data.lhs,
1214 .value_expr = extra.value_expr,
1215 .align_expr = extra.align_expr,
1216 });
1217}
1218
1219pub fn containerFieldInit(tree: Tree, node: Node.Index) full.ContainerField {
1220 assert(tree.nodes.items(.tag)[node] == .container_field_init);
1221 const data = tree.nodes.items(.data)[node];
1222 return tree.fullContainerField(.{
1223 .name_token = tree.nodes.items(.main_token)[node],
1224 .type_expr = data.lhs,
1225 .value_expr = data.rhs,
1226 .align_expr = 0,
1227 });
1228}
1229
1230pub fn containerFieldAlign(tree: Tree, node: Node.Index) full.ContainerField {
1231 assert(tree.nodes.items(.tag)[node] == .container_field_align);
1232 const data = tree.nodes.items(.data)[node];
1233 return tree.fullContainerField(.{
1234 .name_token = tree.nodes.items(.main_token)[node],
1235 .type_expr = data.lhs,
1236 .value_expr = 0,
1237 .align_expr = data.rhs,
1238 });
1239}
1240
1241pub fn fnProtoSimple(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.FnProto {
1242 assert(tree.nodes.items(.tag)[node] == .fn_proto_simple);
1243 const data = tree.nodes.items(.data)[node];
1244 buffer[0] = data.lhs;
1245 const params = if (data.lhs == 0) buffer[0..0] else buffer[0..1];
1246 return tree.fullFnProto(.{
1247 .proto_node = node,
1248 .fn_token = tree.nodes.items(.main_token)[node],
1249 .return_type = data.rhs,
1250 .params = params,
1251 .align_expr = 0,
1252 .section_expr = 0,
1253 .callconv_expr = 0,
1254 });
1255}
1256
1257pub fn fnProtoMulti(tree: Tree, node: Node.Index) full.FnProto {
1258 assert(tree.nodes.items(.tag)[node] == .fn_proto_multi);
1259 const data = tree.nodes.items(.data)[node];
1260 const params_range = tree.extraData(data.lhs, Node.SubRange);
1261 const params = tree.extra_data[params_range.start..params_range.end];
1262 return tree.fullFnProto(.{
1263 .proto_node = node,
1264 .fn_token = tree.nodes.items(.main_token)[node],
1265 .return_type = data.rhs,
1266 .params = params,
1267 .align_expr = 0,
1268 .section_expr = 0,
1269 .callconv_expr = 0,
1270 });
1271}
1272
1273pub fn fnProtoOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.FnProto {
1274 assert(tree.nodes.items(.tag)[node] == .fn_proto_one);
1275 const data = tree.nodes.items(.data)[node];
1276 const extra = tree.extraData(data.lhs, Node.FnProtoOne);
1277 buffer[0] = extra.param;
1278 const params = if (extra.param == 0) buffer[0..0] else buffer[0..1];
1279 return tree.fullFnProto(.{
1280 .proto_node = node,
1281 .fn_token = tree.nodes.items(.main_token)[node],
1282 .return_type = data.rhs,
1283 .params = params,
1284 .align_expr = extra.align_expr,
1285 .section_expr = extra.section_expr,
1286 .callconv_expr = extra.callconv_expr,
1287 });
1288}
1289
1290pub fn fnProto(tree: Tree, node: Node.Index) full.FnProto {
1291 assert(tree.nodes.items(.tag)[node] == .fn_proto);
1292 const data = tree.nodes.items(.data)[node];
1293 const extra = tree.extraData(data.lhs, Node.FnProto);
1294 const params = tree.extra_data[extra.params_start..extra.params_end];
1295 return tree.fullFnProto(.{
1296 .proto_node = node,
1297 .fn_token = tree.nodes.items(.main_token)[node],
1298 .return_type = data.rhs,
1299 .params = params,
1300 .align_expr = extra.align_expr,
1301 .section_expr = extra.section_expr,
1302 .callconv_expr = extra.callconv_expr,
1303 });
1304}
1305
1306pub fn structInitOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.StructInit {
1307 assert(tree.nodes.items(.tag)[node] == .struct_init_one or
1308 tree.nodes.items(.tag)[node] == .struct_init_one_comma);
1309 const data = tree.nodes.items(.data)[node];
1310 buffer[0] = data.rhs;
1311 const fields = if (data.rhs == 0) buffer[0..0] else buffer[0..1];
1312 return tree.fullStructInit(.{
1313 .lbrace = tree.nodes.items(.main_token)[node],
1314 .fields = fields,
1315 .type_expr = data.lhs,
1316 });
1317}
1318
1319pub fn structInitDotTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.StructInit {
1320 assert(tree.nodes.items(.tag)[node] == .struct_init_dot_two or
1321 tree.nodes.items(.tag)[node] == .struct_init_dot_two_comma);
1322 const data = tree.nodes.items(.data)[node];
1323 buffer.* = .{ data.lhs, data.rhs };
1324 const fields = if (data.rhs != 0)
1325 buffer[0..2]
1326 else if (data.lhs != 0)
1327 buffer[0..1]
1328 else
1329 buffer[0..0];
1330 return tree.fullStructInit(.{
1331 .lbrace = tree.nodes.items(.main_token)[node],
1332 .fields = fields,
1333 .type_expr = 0,
1334 });
1335}
1336
1337pub fn structInitDot(tree: Tree, node: Node.Index) full.StructInit {
1338 assert(tree.nodes.items(.tag)[node] == .struct_init_dot or
1339 tree.nodes.items(.tag)[node] == .struct_init_dot_comma);
1340 const data = tree.nodes.items(.data)[node];
1341 return tree.fullStructInit(.{
1342 .lbrace = tree.nodes.items(.main_token)[node],
1343 .fields = tree.extra_data[data.lhs..data.rhs],
1344 .type_expr = 0,
1345 });
1346}
1347
1348pub fn structInit(tree: Tree, node: Node.Index) full.StructInit {
1349 assert(tree.nodes.items(.tag)[node] == .struct_init or
1350 tree.nodes.items(.tag)[node] == .struct_init_comma);
1351 const data = tree.nodes.items(.data)[node];
1352 const fields_range = tree.extraData(data.rhs, Node.SubRange);
1353 return tree.fullStructInit(.{
1354 .lbrace = tree.nodes.items(.main_token)[node],
1355 .fields = tree.extra_data[fields_range.start..fields_range.end],
1356 .type_expr = data.lhs,
1357 });
1358}
1359
1360pub fn arrayInitOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.ArrayInit {
1361 assert(tree.nodes.items(.tag)[node] == .array_init_one or
1362 tree.nodes.items(.tag)[node] == .array_init_one_comma);
1363 const data = tree.nodes.items(.data)[node];
1364 buffer[0] = data.rhs;
1365 const elements = if (data.rhs == 0) buffer[0..0] else buffer[0..1];
1366 return .{
1367 .ast = .{
1368 .lbrace = tree.nodes.items(.main_token)[node],
1369 .elements = elements,
1370 .type_expr = data.lhs,
1371 },
1372 };
1373}
1374
1375pub fn arrayInitDotTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.ArrayInit {
1376 assert(tree.nodes.items(.tag)[node] == .array_init_dot_two or
1377 tree.nodes.items(.tag)[node] == .array_init_dot_two_comma);
1378 const data = tree.nodes.items(.data)[node];
1379 buffer.* = .{ data.lhs, data.rhs };
1380 const elements = if (data.rhs != 0)
1381 buffer[0..2]
1382 else if (data.lhs != 0)
1383 buffer[0..1]
1384 else
1385 buffer[0..0];
1386 return .{
1387 .ast = .{
1388 .lbrace = tree.nodes.items(.main_token)[node],
1389 .elements = elements,
1390 .type_expr = 0,
1391 },
1392 };
1393}
1394
1395pub fn arrayInitDot(tree: Tree, node: Node.Index) full.ArrayInit {
1396 assert(tree.nodes.items(.tag)[node] == .array_init_dot or
1397 tree.nodes.items(.tag)[node] == .array_init_dot_comma);
1398 const data = tree.nodes.items(.data)[node];
1399 return .{
1400 .ast = .{
1401 .lbrace = tree.nodes.items(.main_token)[node],
1402 .elements = tree.extra_data[data.lhs..data.rhs],
1403 .type_expr = 0,
1404 },
1405 };
1406}
1407
1408pub fn arrayInit(tree: Tree, node: Node.Index) full.ArrayInit {
1409 assert(tree.nodes.items(.tag)[node] == .array_init or
1410 tree.nodes.items(.tag)[node] == .array_init_comma);
1411 const data = tree.nodes.items(.data)[node];
1412 const elem_range = tree.extraData(data.rhs, Node.SubRange);
1413 return .{
1414 .ast = .{
1415 .lbrace = tree.nodes.items(.main_token)[node],
1416 .elements = tree.extra_data[elem_range.start..elem_range.end],
1417 .type_expr = data.lhs,
1418 },
1419 };
1420}
1421
1422pub fn arrayType(tree: Tree, node: Node.Index) full.ArrayType {
1423 assert(tree.nodes.items(.tag)[node] == .array_type);
1424 const data = tree.nodes.items(.data)[node];
1425 return .{
1426 .ast = .{
1427 .lbracket = tree.nodes.items(.main_token)[node],
1428 .elem_count = data.lhs,
1429 .sentinel = 0,
1430 .elem_type = data.rhs,
1431 },
1432 };
1433}
1434
1435pub fn arrayTypeSentinel(tree: Tree, node: Node.Index) full.ArrayType {
1436 assert(tree.nodes.items(.tag)[node] == .array_type_sentinel);
1437 const data = tree.nodes.items(.data)[node];
1438 const extra = tree.extraData(data.rhs, Node.ArrayTypeSentinel);
1439 assert(extra.sentinel != 0);
1440 return .{
1441 .ast = .{
1442 .lbracket = tree.nodes.items(.main_token)[node],
1443 .elem_count = data.lhs,
1444 .sentinel = extra.sentinel,
1445 .elem_type = extra.elem_type,
1446 },
1447 };
1448}
1449
1450pub fn ptrTypeAligned(tree: Tree, node: Node.Index) full.PtrType {
1451 assert(tree.nodes.items(.tag)[node] == .ptr_type_aligned);
1452 const data = tree.nodes.items(.data)[node];
1453 return tree.fullPtrType(.{
1454 .main_token = tree.nodes.items(.main_token)[node],
1455 .align_node = data.lhs,
1456 .sentinel = 0,
1457 .bit_range_start = 0,
1458 .bit_range_end = 0,
1459 .child_type = data.rhs,
1460 });
1461}
1462
1463pub fn ptrTypeSentinel(tree: Tree, node: Node.Index) full.PtrType {
1464 assert(tree.nodes.items(.tag)[node] == .ptr_type_sentinel);
1465 const data = tree.nodes.items(.data)[node];
1466 return tree.fullPtrType(.{
1467 .main_token = tree.nodes.items(.main_token)[node],
1468 .align_node = 0,
1469 .sentinel = data.lhs,
1470 .bit_range_start = 0,
1471 .bit_range_end = 0,
1472 .child_type = data.rhs,
1473 });
1474}
1475
1476pub fn ptrType(tree: Tree, node: Node.Index) full.PtrType {
1477 assert(tree.nodes.items(.tag)[node] == .ptr_type);
1478 const data = tree.nodes.items(.data)[node];
1479 const extra = tree.extraData(data.lhs, Node.PtrType);
1480 return tree.fullPtrType(.{
1481 .main_token = tree.nodes.items(.main_token)[node],
1482 .align_node = extra.align_node,
1483 .sentinel = extra.sentinel,
1484 .bit_range_start = 0,
1485 .bit_range_end = 0,
1486 .child_type = data.rhs,
1487 });
1488}
1489
1490pub fn ptrTypeBitRange(tree: Tree, node: Node.Index) full.PtrType {
1491 assert(tree.nodes.items(.tag)[node] == .ptr_type_bit_range);
1492 const data = tree.nodes.items(.data)[node];
1493 const extra = tree.extraData(data.lhs, Node.PtrTypeBitRange);
1494 return tree.fullPtrType(.{
1495 .main_token = tree.nodes.items(.main_token)[node],
1496 .align_node = extra.align_node,
1497 .sentinel = extra.sentinel,
1498 .bit_range_start = extra.bit_range_start,
1499 .bit_range_end = extra.bit_range_end,
1500 .child_type = data.rhs,
1501 });
1502}
1503
1504pub fn sliceOpen(tree: Tree, node: Node.Index) full.Slice {
1505 assert(tree.nodes.items(.tag)[node] == .slice_open);
1506 const data = tree.nodes.items(.data)[node];
1507 return .{
1508 .ast = .{
1509 .sliced = data.lhs,
1510 .lbracket = tree.nodes.items(.main_token)[node],
1511 .start = data.rhs,
1512 .end = 0,
1513 .sentinel = 0,
1514 },
1515 };
1516}
1517
1518pub fn slice(tree: Tree, node: Node.Index) full.Slice {
1519 assert(tree.nodes.items(.tag)[node] == .slice);
1520 const data = tree.nodes.items(.data)[node];
1521 const extra = tree.extraData(data.rhs, Node.Slice);
1522 return .{
1523 .ast = .{
1524 .sliced = data.lhs,
1525 .lbracket = tree.nodes.items(.main_token)[node],
1526 .start = extra.start,
1527 .end = extra.end,
1528 .sentinel = 0,
1529 },
1530 };
1531}
1532
1533pub fn sliceSentinel(tree: Tree, node: Node.Index) full.Slice {
1534 assert(tree.nodes.items(.tag)[node] == .slice_sentinel);
1535 const data = tree.nodes.items(.data)[node];
1536 const extra = tree.extraData(data.rhs, Node.SliceSentinel);
1537 return .{
1538 .ast = .{
1539 .sliced = data.lhs,
1540 .lbracket = tree.nodes.items(.main_token)[node],
1541 .start = extra.start,
1542 .end = extra.end,
1543 .sentinel = extra.sentinel,
1544 },
1545 };
1546}
1547
1548pub fn containerDeclTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl {
1549 assert(tree.nodes.items(.tag)[node] == .container_decl_two or
1550 tree.nodes.items(.tag)[node] == .container_decl_two_trailing);
1551 const data = tree.nodes.items(.data)[node];
1552 buffer.* = .{ data.lhs, data.rhs };
1553 const members = if (data.rhs != 0)
1554 buffer[0..2]
1555 else if (data.lhs != 0)
1556 buffer[0..1]
1557 else
1558 buffer[0..0];
1559 return tree.fullContainerDecl(.{
1560 .main_token = tree.nodes.items(.main_token)[node],
1561 .enum_token = null,
1562 .members = members,
1563 .arg = 0,
1564 });
1565}
1566
1567pub fn containerDecl(tree: Tree, node: Node.Index) full.ContainerDecl {
1568 assert(tree.nodes.items(.tag)[node] == .container_decl or
1569 tree.nodes.items(.tag)[node] == .container_decl_trailing);
1570 const data = tree.nodes.items(.data)[node];
1571 return tree.fullContainerDecl(.{
1572 .main_token = tree.nodes.items(.main_token)[node],
1573 .enum_token = null,
1574 .members = tree.extra_data[data.lhs..data.rhs],
1575 .arg = 0,
1576 });
1577}
1578
1579pub fn containerDeclArg(tree: Tree, node: Node.Index) full.ContainerDecl {
1580 assert(tree.nodes.items(.tag)[node] == .container_decl_arg or
1581 tree.nodes.items(.tag)[node] == .container_decl_arg_trailing);
1582 const data = tree.nodes.items(.data)[node];
1583 const members_range = tree.extraData(data.rhs, Node.SubRange);
1584 return tree.fullContainerDecl(.{
1585 .main_token = tree.nodes.items(.main_token)[node],
1586 .enum_token = null,
1587 .members = tree.extra_data[members_range.start..members_range.end],
1588 .arg = data.lhs,
1589 });
1590}
1591
1592pub fn taggedUnionTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl {
1593 assert(tree.nodes.items(.tag)[node] == .tagged_union_two or
1594 tree.nodes.items(.tag)[node] == .tagged_union_two_trailing);
1595 const data = tree.nodes.items(.data)[node];
1596 buffer.* = .{ data.lhs, data.rhs };
1597 const members = if (data.rhs != 0)
1598 buffer[0..2]
1599 else if (data.lhs != 0)
1600 buffer[0..1]
1601 else
1602 buffer[0..0];
1603 const main_token = tree.nodes.items(.main_token)[node];
1604 return tree.fullContainerDecl(.{
1605 .main_token = main_token,
1606 .enum_token = main_token + 2, // union lparen enum
1607 .members = members,
1608 .arg = 0,
1609 });
1610}
1611
1612pub fn taggedUnion(tree: Tree, node: Node.Index) full.ContainerDecl {
1613 assert(tree.nodes.items(.tag)[node] == .tagged_union or
1614 tree.nodes.items(.tag)[node] == .tagged_union_trailing);
1615 const data = tree.nodes.items(.data)[node];
1616 const main_token = tree.nodes.items(.main_token)[node];
1617 return tree.fullContainerDecl(.{
1618 .main_token = main_token,
1619 .enum_token = main_token + 2, // union lparen enum
1620 .members = tree.extra_data[data.lhs..data.rhs],
1621 .arg = 0,
1622 });
1623}
1624
1625pub fn taggedUnionEnumTag(tree: Tree, node: Node.Index) full.ContainerDecl {
1626 assert(tree.nodes.items(.tag)[node] == .tagged_union_enum_tag or
1627 tree.nodes.items(.tag)[node] == .tagged_union_enum_tag_trailing);
1628 const data = tree.nodes.items(.data)[node];
1629 const members_range = tree.extraData(data.rhs, Node.SubRange);
1630 const main_token = tree.nodes.items(.main_token)[node];
1631 return tree.fullContainerDecl(.{
1632 .main_token = main_token,
1633 .enum_token = main_token + 2, // union lparen enum
1634 .members = tree.extra_data[members_range.start..members_range.end],
1635 .arg = data.lhs,
1636 });
1637}
1638
1639pub fn switchCaseOne(tree: Tree, node: Node.Index) full.SwitchCase {
1640 const data = &tree.nodes.items(.data)[node];
1641 const values: *[1]Node.Index = &data.lhs;
1642 return tree.fullSwitchCase(.{
1643 .values = if (data.lhs == 0) values[0..0] else values[0..1],
1644 .arrow_token = tree.nodes.items(.main_token)[node],
1645 .target_expr = data.rhs,
1646 });
1647}
1648
1649pub fn switchCase(tree: Tree, node: Node.Index) full.SwitchCase {
1650 const data = tree.nodes.items(.data)[node];
1651 const extra = tree.extraData(data.lhs, Node.SubRange);
1652 return tree.fullSwitchCase(.{
1653 .values = tree.extra_data[extra.start..extra.end],
1654 .arrow_token = tree.nodes.items(.main_token)[node],
1655 .target_expr = data.rhs,
1656 });
1657}
1658
1659pub fn asmSimple(tree: Tree, node: Node.Index) full.Asm {
1660 const data = tree.nodes.items(.data)[node];
1661 return tree.fullAsm(.{
1662 .asm_token = tree.nodes.items(.main_token)[node],
1663 .template = data.lhs,
1664 .items = &.{},
1665 .rparen = data.rhs,
1666 });
1667}
1668
1669pub fn asmFull(tree: Tree, node: Node.Index) full.Asm {
1670 const data = tree.nodes.items(.data)[node];
1671 const extra = tree.extraData(data.rhs, Node.Asm);
1672 return tree.fullAsm(.{
1673 .asm_token = tree.nodes.items(.main_token)[node],
1674 .template = data.lhs,
1675 .items = tree.extra_data[extra.items_start..extra.items_end],
1676 .rparen = extra.rparen,
1677 });
1678}
1679
1680pub fn whileSimple(tree: Tree, node: Node.Index) full.While {
1681 const data = tree.nodes.items(.data)[node];
1682 return tree.fullWhile(.{
1683 .while_token = tree.nodes.items(.main_token)[node],
1684 .cond_expr = data.lhs,
1685 .cont_expr = 0,
1686 .then_expr = data.rhs,
1687 .else_expr = 0,
1688 });
1689}
1690
1691pub fn whileCont(tree: Tree, node: Node.Index) full.While {
1692 const data = tree.nodes.items(.data)[node];
1693 const extra = tree.extraData(data.rhs, Node.WhileCont);
1694 return tree.fullWhile(.{
1695 .while_token = tree.nodes.items(.main_token)[node],
1696 .cond_expr = data.lhs,
1697 .cont_expr = extra.cont_expr,
1698 .then_expr = extra.then_expr,
1699 .else_expr = 0,
1700 });
1701}
1702
1703pub fn whileFull(tree: Tree, node: Node.Index) full.While {
1704 const data = tree.nodes.items(.data)[node];
1705 const extra = tree.extraData(data.rhs, Node.While);
1706 return tree.fullWhile(.{
1707 .while_token = tree.nodes.items(.main_token)[node],
1708 .cond_expr = data.lhs,
1709 .cont_expr = extra.cont_expr,
1710 .then_expr = extra.then_expr,
1711 .else_expr = extra.else_expr,
1712 });
1713}
1714
1715pub fn forSimple(tree: Tree, node: Node.Index) full.While {
1716 const data = tree.nodes.items(.data)[node];
1717 return tree.fullWhile(.{
1718 .while_token = tree.nodes.items(.main_token)[node],
1719 .cond_expr = data.lhs,
1720 .cont_expr = 0,
1721 .then_expr = data.rhs,
1722 .else_expr = 0,
1723 });
1724}
1725
1726pub fn forFull(tree: Tree, node: Node.Index) full.While {
1727 const data = tree.nodes.items(.data)[node];
1728 const extra = tree.extraData(data.rhs, Node.If);
1729 return tree.fullWhile(.{
1730 .while_token = tree.nodes.items(.main_token)[node],
1731 .cond_expr = data.lhs,
1732 .cont_expr = 0,
1733 .then_expr = extra.then_expr,
1734 .else_expr = extra.else_expr,
1735 });
1736}
1737
1738pub fn callOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.Call {
1739 const data = tree.nodes.items(.data)[node];
1740 buffer.* = .{data.rhs};
1741 const params = if (data.rhs != 0) buffer[0..1] else buffer[0..0];
1742 return tree.fullCall(.{
1743 .lparen = tree.nodes.items(.main_token)[node],
1744 .fn_expr = data.lhs,
1745 .params = params,
1746 });
1747}
1748
1749pub fn callFull(tree: Tree, node: Node.Index) full.Call {
1750 const data = tree.nodes.items(.data)[node];
1751 const extra = tree.extraData(data.rhs, Node.SubRange);
1752 return tree.fullCall(.{
1753 .lparen = tree.nodes.items(.main_token)[node],
1754 .fn_expr = data.lhs,
1755 .params = tree.extra_data[extra.start..extra.end],
1756 });
1757}
1758
1759fn fullVarDecl(tree: Tree, info: full.VarDecl.Components) full.VarDecl {
1760 const token_tags = tree.tokens.items(.tag);
1761 var result: full.VarDecl = .{
1762 .ast = info,
1763 .visib_token = null,
1764 .extern_export_token = null,
1765 .lib_name = null,
1766 .threadlocal_token = null,
1767 .comptime_token = null,
1768 };
1769 var i = info.mut_token;
1770 while (i > 0) {
1771 i -= 1;
1772 switch (token_tags[i]) {
1773 .keyword_extern, .keyword_export => result.extern_export_token = i,
1774 .keyword_comptime => result.comptime_token = i,
1775 .keyword_pub => result.visib_token = i,
1776 .keyword_threadlocal => result.threadlocal_token = i,
1777 .string_literal => result.lib_name = i,
1778 else => break,
1779 }
1780 }
1781 return result;
1782}
1783
1784fn fullIf(tree: Tree, info: full.If.Components) full.If {
1785 const token_tags = tree.tokens.items(.tag);
1786 var result: full.If = .{
1787 .ast = info,
1788 .payload_token = null,
1789 .error_token = null,
1790 .else_token = undefined,
1791 };
1792 // if (cond_expr) |x|
1793 // ^ ^
1794 const payload_pipe = tree.lastToken(info.cond_expr) + 2;
1795 if (token_tags[payload_pipe] == .pipe) {
1796 result.payload_token = payload_pipe + 1;
1797 }
1798 if (info.else_expr != 0) {
1799 // then_expr else |x|
1800 // ^ ^
1801 result.else_token = tree.lastToken(info.then_expr) + 1;
1802 if (token_tags[result.else_token + 1] == .pipe) {
1803 result.error_token = result.else_token + 2;
1804 }
1805 }
1806 return result;
1807}
1808
1809fn fullContainerField(tree: Tree, info: full.ContainerField.Components) full.ContainerField {
1810 const token_tags = tree.tokens.items(.tag);
1811 var result: full.ContainerField = .{
1812 .ast = info,
1813 .comptime_token = null,
1814 };
1815 // comptime name: type = init,
1816 // ^
1817 if (info.name_token > 0 and token_tags[info.name_token - 1] == .keyword_comptime) {
1818 result.comptime_token = info.name_token - 1;
1819 }
1820 return result;
1821}
1822
1823fn fullFnProto(tree: Tree, info: full.FnProto.Components) full.FnProto {
1824 const token_tags = tree.tokens.items(.tag);
1825 var result: full.FnProto = .{
1826 .ast = info,
1827 .visib_token = null,
1828 .extern_export_inline_token = null,
1829 .lib_name = null,
1830 .name_token = null,
1831 .lparen = undefined,
1832 };
1833 var i = info.fn_token;
1834 while (i > 0) {
1835 i -= 1;
1836 switch (token_tags[i]) {
1837 .keyword_extern,
1838 .keyword_export,
1839 .keyword_inline,
1840 .keyword_noinline,
1841 => result.extern_export_inline_token = i,
1842 .keyword_pub => result.visib_token = i,
1843 .string_literal => result.lib_name = i,
1844 else => break,
1845 }
1846 }
1847 const after_fn_token = info.fn_token + 1;
1848 if (token_tags[after_fn_token] == .identifier) {
1849 result.name_token = after_fn_token;
1850 result.lparen = after_fn_token + 1;
1851 } else {
1852 result.lparen = after_fn_token;
1853 }
1854 assert(token_tags[result.lparen] == .l_paren);
1855
1856 return result;
1857}
1858
1859fn fullStructInit(tree: Tree, info: full.StructInit.Components) full.StructInit {
1860 _ = tree;
1861 var result: full.StructInit = .{
1862 .ast = info,
1863 };
1864 return result;
1865}
1866
1867fn fullPtrType(tree: Tree, info: full.PtrType.Components) full.PtrType {
1868 const token_tags = tree.tokens.items(.tag);
1869 // TODO: looks like stage1 isn't quite smart enough to handle enum
1870 // literals in some places here
1871 const Size = std.builtin.TypeInfo.Pointer.Size;
1872 const size: Size = switch (token_tags[info.main_token]) {
1873 .asterisk,
1874 .asterisk_asterisk,
1875 => switch (token_tags[info.main_token + 1]) {
1876 .r_bracket, .colon => .Many,
1877 .identifier => if (token_tags[info.main_token - 1] == .l_bracket) Size.C else .One,
1878 else => .One,
1879 },
1880 .l_bracket => Size.Slice,
1881 else => unreachable,
1882 };
1883 var result: full.PtrType = .{
1884 .size = size,
1885 .allowzero_token = null,
1886 .const_token = null,
1887 .volatile_token = null,
1888 .ast = info,
1889 };
1890 // We need to be careful that we don't iterate over any sub-expressions
1891 // here while looking for modifiers as that could result in false
1892 // positives. Therefore, start after a sentinel if there is one and
1893 // skip over any align node and bit range nodes.
1894 var i = if (info.sentinel != 0) tree.lastToken(info.sentinel) + 1 else info.main_token;
1895 const end = tree.firstToken(info.child_type);
1896 while (i < end) : (i += 1) {
1897 switch (token_tags[i]) {
1898 .keyword_allowzero => result.allowzero_token = i,
1899 .keyword_const => result.const_token = i,
1900 .keyword_volatile => result.volatile_token = i,
1901 .keyword_align => {
1902 assert(info.align_node != 0);
1903 if (info.bit_range_end != 0) {
1904 assert(info.bit_range_start != 0);
1905 i = tree.lastToken(info.bit_range_end) + 1;
1906 } else {
1907 i = tree.lastToken(info.align_node) + 1;
1908 }
1909 },
1910 else => {},
1911 }
1912 }
1913 return result;
1914}
1915
1916fn fullContainerDecl(tree: Tree, info: full.ContainerDecl.Components) full.ContainerDecl {
1917 const token_tags = tree.tokens.items(.tag);
1918 var result: full.ContainerDecl = .{
1919 .ast = info,
1920 .layout_token = null,
1921 };
1922 switch (token_tags[info.main_token - 1]) {
1923 .keyword_extern, .keyword_packed => result.layout_token = info.main_token - 1,
1924 else => {},
1925 }
1926 return result;
1927}
1928
1929fn fullSwitchCase(tree: Tree, info: full.SwitchCase.Components) full.SwitchCase {
1930 const token_tags = tree.tokens.items(.tag);
1931 var result: full.SwitchCase = .{
1932 .ast = info,
1933 .payload_token = null,
1934 };
1935 if (token_tags[info.arrow_token + 1] == .pipe) {
1936 result.payload_token = info.arrow_token + 2;
1937 }
1938 return result;
1939}
1940
1941fn fullAsm(tree: Tree, info: full.Asm.Components) full.Asm {
1942 const token_tags = tree.tokens.items(.tag);
1943 const node_tags = tree.nodes.items(.tag);
1944 var result: full.Asm = .{
1945 .ast = info,
1946 .volatile_token = null,
1947 .inputs = &.{},
1948 .outputs = &.{},
1949 .first_clobber = null,
1950 };
1951 if (token_tags[info.asm_token + 1] == .keyword_volatile) {
1952 result.volatile_token = info.asm_token + 1;
1953 }
1954 const outputs_end: usize = for (info.items) |item, i| {
1955 switch (node_tags[item]) {
1956 .asm_output => continue,
1957 else => break i,
1958 }
1959 } else info.items.len;
1960
1961 result.outputs = info.items[0..outputs_end];
1962 result.inputs = info.items[outputs_end..];
1963
1964 if (info.items.len == 0) {
1965 // asm ("foo" ::: "a", "b");
1966 const template_token = tree.lastToken(info.template);
1967 if (token_tags[template_token + 1] == .colon and
1968 token_tags[template_token + 2] == .colon and
1969 token_tags[template_token + 3] == .colon and
1970 token_tags[template_token + 4] == .string_literal)
1971 {
1972 result.first_clobber = template_token + 4;
1973 }
1974 } else if (result.inputs.len != 0) {
1975 // asm ("foo" :: [_] "" (y) : "a", "b");
1976 const last_input = result.inputs[result.inputs.len - 1];
1977 const rparen = tree.lastToken(last_input);
1978 var i = rparen + 1;
1979 // Allow a (useless) comma right after the closing parenthesis.
1980 if (token_tags[i] == .comma) i += 1;
1981 if (token_tags[i] == .colon and
1982 token_tags[i + 1] == .string_literal)
1983 {
1984 result.first_clobber = i + 1;
1985 }
1986 } else {
1987 // asm ("foo" : [_] "" (x) :: "a", "b");
1988 const last_output = result.outputs[result.outputs.len - 1];
1989 const rparen = tree.lastToken(last_output);
1990 var i = rparen + 1;
1991 // Allow a (useless) comma right after the closing parenthesis.
1992 if (token_tags[i] == .comma) i += 1;
1993 if (token_tags[i] == .colon and
1994 token_tags[i + 1] == .colon and
1995 token_tags[i + 2] == .string_literal)
1996 {
1997 result.first_clobber = i + 2;
1998 }
1999 }
2000
2001 return result;
2002}
2003
2004fn fullWhile(tree: Tree, info: full.While.Components) full.While {
2005 const token_tags = tree.tokens.items(.tag);
2006 var result: full.While = .{
2007 .ast = info,
2008 .inline_token = null,
2009 .label_token = null,
2010 .payload_token = null,
2011 .else_token = undefined,
2012 .error_token = null,
2013 };
2014 var tok_i = info.while_token - 1;
2015 if (token_tags[tok_i] == .keyword_inline) {
2016 result.inline_token = tok_i;
2017 tok_i -= 1;
2018 }
2019 if (token_tags[tok_i] == .colon and
2020 token_tags[tok_i - 1] == .identifier)
2021 {
2022 result.label_token = tok_i - 1;
2023 }
2024 const last_cond_token = tree.lastToken(info.cond_expr);
2025 if (token_tags[last_cond_token + 2] == .pipe) {
2026 result.payload_token = last_cond_token + 3;
2027 }
2028 if (info.else_expr != 0) {
2029 // then_expr else |x|
2030 // ^ ^
2031 result.else_token = tree.lastToken(info.then_expr) + 1;
2032 if (token_tags[result.else_token + 1] == .pipe) {
2033 result.error_token = result.else_token + 2;
2034 }
2035 }
2036 return result;
2037}
2038
2039fn fullCall(tree: Tree, info: full.Call.Components) full.Call {
2040 const token_tags = tree.tokens.items(.tag);
2041 var result: full.Call = .{
2042 .ast = info,
2043 .async_token = null,
2044 };
2045 const maybe_async_token = tree.firstToken(info.fn_expr) - 1;
2046 if (token_tags[maybe_async_token] == .keyword_async) {
2047 result.async_token = maybe_async_token;
2048 }
2049 return result;
2050}
2051
2052/// Fully assembled AST node information.
2053pub const full = struct {
2054 pub const VarDecl = struct {
2055 visib_token: ?TokenIndex,
2056 extern_export_token: ?TokenIndex,
2057 lib_name: ?TokenIndex,
2058 threadlocal_token: ?TokenIndex,
2059 comptime_token: ?TokenIndex,
2060 ast: Components,
2061
2062 pub const Components = struct {
2063 mut_token: TokenIndex,
2064 type_node: Node.Index,
2065 align_node: Node.Index,
2066 section_node: Node.Index,
2067 init_node: Node.Index,
2068 };
2069 };
2070
2071 pub const If = struct {
2072 /// Points to the first token after the `|`. Will either be an identifier or
2073 /// a `*` (with an identifier immediately after it).
2074 payload_token: ?TokenIndex,
2075 /// Points to the identifier after the `|`.
2076 error_token: ?TokenIndex,
2077 /// Populated only if else_expr != 0.
2078 else_token: TokenIndex,
2079 ast: Components,
2080
2081 pub const Components = struct {
2082 if_token: TokenIndex,
2083 cond_expr: Node.Index,
2084 then_expr: Node.Index,
2085 else_expr: Node.Index,
2086 };
2087 };
2088
2089 pub const While = struct {
2090 ast: Components,
2091 inline_token: ?TokenIndex,
2092 label_token: ?TokenIndex,
2093 payload_token: ?TokenIndex,
2094 error_token: ?TokenIndex,
2095 /// Populated only if else_expr != 0.
2096 else_token: TokenIndex,
2097
2098 pub const Components = struct {
2099 while_token: TokenIndex,
2100 cond_expr: Node.Index,
2101 cont_expr: Node.Index,
2102 then_expr: Node.Index,
2103 else_expr: Node.Index,
2104 };
2105 };
2106
2107 pub const ContainerField = struct {
2108 comptime_token: ?TokenIndex,
2109 ast: Components,
2110
2111 pub const Components = struct {
2112 name_token: TokenIndex,
2113 type_expr: Node.Index,
2114 value_expr: Node.Index,
2115 align_expr: Node.Index,
2116 };
2117 };
2118
2119 pub const FnProto = struct {
2120 visib_token: ?TokenIndex,
2121 extern_export_inline_token: ?TokenIndex,
2122 lib_name: ?TokenIndex,
2123 name_token: ?TokenIndex,
2124 lparen: TokenIndex,
2125 ast: Components,
2126
2127 pub const Components = struct {
2128 proto_node: Node.Index,
2129 fn_token: TokenIndex,
2130 return_type: Node.Index,
2131 params: []const Node.Index,
2132 align_expr: Node.Index,
2133 section_expr: Node.Index,
2134 callconv_expr: Node.Index,
2135 };
2136
2137 pub const Param = struct {
2138 first_doc_comment: ?TokenIndex,
2139 name_token: ?TokenIndex,
2140 comptime_noalias: ?TokenIndex,
2141 anytype_ellipsis3: ?TokenIndex,
2142 type_expr: Node.Index,
2143 };
2144
2145 /// Abstracts over the fact that anytype and ... are not included
2146 /// in the params slice, since they are simple identifiers and
2147 /// not sub-expressions.
2148 pub const Iterator = struct {
2149 tree: *const Tree,
2150 fn_proto: *const FnProto,
2151 param_i: usize,
2152 tok_i: TokenIndex,
2153 tok_flag: bool,
2154
2155 pub fn next(it: *Iterator) ?Param {
2156 const token_tags = it.tree.tokens.items(.tag);
2157 while (true) {
2158 var first_doc_comment: ?TokenIndex = null;
2159 var comptime_noalias: ?TokenIndex = null;
2160 var name_token: ?TokenIndex = null;
2161 if (!it.tok_flag) {
2162 if (it.param_i >= it.fn_proto.ast.params.len) {
2163 return null;
2164 }
2165 const param_type = it.fn_proto.ast.params[it.param_i];
2166 var tok_i = it.tree.firstToken(param_type) - 1;
2167 while (true) : (tok_i -= 1) switch (token_tags[tok_i]) {
2168 .colon => continue,
2169 .identifier => name_token = tok_i,
2170 .doc_comment => first_doc_comment = tok_i,
2171 .keyword_comptime, .keyword_noalias => comptime_noalias = tok_i,
2172 else => break,
2173 };
2174 it.param_i += 1;
2175 it.tok_i = it.tree.lastToken(param_type) + 1;
2176 // Look for anytype and ... params afterwards.
2177 if (token_tags[it.tok_i] == .comma) {
2178 it.tok_i += 1;
2179 }
2180 it.tok_flag = true;
2181 return Param{
2182 .first_doc_comment = first_doc_comment,
2183 .comptime_noalias = comptime_noalias,
2184 .name_token = name_token,
2185 .anytype_ellipsis3 = null,
2186 .type_expr = param_type,
2187 };
2188 }
2189 if (token_tags[it.tok_i] == .comma) {
2190 it.tok_i += 1;
2191 }
2192 if (token_tags[it.tok_i] == .r_paren) {
2193 return null;
2194 }
2195 if (token_tags[it.tok_i] == .doc_comment) {
2196 first_doc_comment = it.tok_i;
2197 while (token_tags[it.tok_i] == .doc_comment) {
2198 it.tok_i += 1;
2199 }
2200 }
2201 switch (token_tags[it.tok_i]) {
2202 .ellipsis3 => {
2203 it.tok_flag = false; // Next iteration should return null.
2204 return Param{
2205 .first_doc_comment = first_doc_comment,
2206 .comptime_noalias = null,
2207 .name_token = null,
2208 .anytype_ellipsis3 = it.tok_i,
2209 .type_expr = 0,
2210 };
2211 },
2212 .keyword_noalias, .keyword_comptime => {
2213 comptime_noalias = it.tok_i;
2214 it.tok_i += 1;
2215 },
2216 else => {},
2217 }
2218 if (token_tags[it.tok_i] == .identifier and
2219 token_tags[it.tok_i + 1] == .colon)
2220 {
2221 name_token = it.tok_i;
2222 it.tok_i += 2;
2223 }
2224 if (token_tags[it.tok_i] == .keyword_anytype) {
2225 it.tok_i += 1;
2226 return Param{
2227 .first_doc_comment = first_doc_comment,
2228 .comptime_noalias = comptime_noalias,
2229 .name_token = name_token,
2230 .anytype_ellipsis3 = it.tok_i - 1,
2231 .type_expr = 0,
2232 };
2233 }
2234 it.tok_flag = false;
2235 }
2236 }
2237 };
2238
2239 pub fn iterate(fn_proto: FnProto, tree: Tree) Iterator {
2240 return .{
2241 .tree = &tree,
2242 .fn_proto = &fn_proto,
2243 .param_i = 0,
2244 .tok_i = fn_proto.lparen + 1,
2245 .tok_flag = true,
2246 };
2247 }
2248 };
2249
2250 pub const StructInit = struct {
2251 ast: Components,
2252
2253 pub const Components = struct {
2254 lbrace: TokenIndex,
2255 fields: []const Node.Index,
2256 type_expr: Node.Index,
2257 };
2258 };
2259
2260 pub const ArrayInit = struct {
2261 ast: Components,
2262
2263 pub const Components = struct {
2264 lbrace: TokenIndex,
2265 elements: []const Node.Index,
2266 type_expr: Node.Index,
2267 };
2268 };
2269
2270 pub const ArrayType = struct {
2271 ast: Components,
2272
2273 pub const Components = struct {
2274 lbracket: TokenIndex,
2275 elem_count: Node.Index,
2276 sentinel: Node.Index,
2277 elem_type: Node.Index,
2278 };
2279 };
2280
2281 pub const PtrType = struct {
2282 size: std.builtin.TypeInfo.Pointer.Size,
2283 allowzero_token: ?TokenIndex,
2284 const_token: ?TokenIndex,
2285 volatile_token: ?TokenIndex,
2286 ast: Components,
2287
2288 pub const Components = struct {
2289 main_token: TokenIndex,
2290 align_node: Node.Index,
2291 sentinel: Node.Index,
2292 bit_range_start: Node.Index,
2293 bit_range_end: Node.Index,
2294 child_type: Node.Index,
2295 };
2296 };
2297
2298 pub const Slice = struct {
2299 ast: Components,
2300
2301 pub const Components = struct {
2302 sliced: Node.Index,
2303 lbracket: TokenIndex,
2304 start: Node.Index,
2305 end: Node.Index,
2306 sentinel: Node.Index,
2307 };
2308 };
2309
2310 pub const ContainerDecl = struct {
2311 layout_token: ?TokenIndex,
2312 ast: Components,
2313
2314 pub const Components = struct {
2315 main_token: TokenIndex,
2316 /// Populated when main_token is Keyword_union.
2317 enum_token: ?TokenIndex,
2318 members: []const Node.Index,
2319 arg: Node.Index,
2320 };
2321 };
2322
2323 pub const SwitchCase = struct {
2324 /// Points to the first token after the `|`. Will either be an identifier or
2325 /// a `*` (with an identifier immediately after it).
2326 payload_token: ?TokenIndex,
2327 ast: Components,
2328
2329 pub const Components = struct {
2330 /// If empty, this is an else case
2331 values: []const Node.Index,
2332 arrow_token: TokenIndex,
2333 target_expr: Node.Index,
2334 };
2335 };
2336
2337 pub const Asm = struct {
2338 ast: Components,
2339 volatile_token: ?TokenIndex,
2340 first_clobber: ?TokenIndex,
2341 outputs: []const Node.Index,
2342 inputs: []const Node.Index,
2343
2344 pub const Components = struct {
2345 asm_token: TokenIndex,
2346 template: Node.Index,
2347 items: []const Node.Index,
2348 rparen: TokenIndex,
2349 };
2350 };
2351
2352 pub const Call = struct {
2353 ast: Components,
2354 async_token: ?TokenIndex,
2355
2356 pub const Components = struct {
2357 lparen: TokenIndex,
2358 fn_expr: Node.Index,
2359 params: []const Node.Index,
2360 };
2361 };
2362};
2363
2364pub const Error = struct {
2365 tag: Tag,
2366 token: TokenIndex,
2367 extra: union {
2368 none: void,
2369 expected_tag: Token.Tag,
2370 } = .{ .none = {} },
2371
2372 pub const Tag = enum {
2373 asterisk_after_ptr_deref,
2374 decl_between_fields,
2375 expected_block,
2376 expected_block_or_assignment,
2377 expected_block_or_expr,
2378 expected_block_or_field,
2379 expected_container_members,
2380 expected_expr,
2381 expected_expr_or_assignment,
2382 expected_fn,
2383 expected_inlinable,
2384 expected_labelable,
2385 expected_param_list,
2386 expected_prefix_expr,
2387 expected_primary_type_expr,
2388 expected_pub_item,
2389 expected_return_type,
2390 expected_semi_or_else,
2391 expected_semi_or_lbrace,
2392 expected_statement,
2393 expected_string_literal,
2394 expected_suffix_op,
2395 expected_type_expr,
2396 expected_var_decl,
2397 expected_var_decl_or_fn,
2398 expected_loop_payload,
2399 expected_container,
2400 extra_align_qualifier,
2401 extra_allowzero_qualifier,
2402 extra_const_qualifier,
2403 extra_volatile_qualifier,
2404 ptr_mod_on_array_child_type,
2405 invalid_bit_range,
2406 invalid_token,
2407 same_line_doc_comment,
2408 unattached_doc_comment,
2409 varargs_nonfinal,
2410
2411 /// `expected_tag` is populated.
2412 expected_token,
2413 };
2414};
2415
2416pub const Node = struct {
2417 tag: Tag,
2418 main_token: TokenIndex,
2419 data: Data,
2420
2421 pub const Index = u32;
2422
2423 comptime {
2424 // Goal is to keep this under one byte for efficiency.
2425 assert(@sizeOf(Tag) == 1);
2426 }
2427
2428 /// Note: The FooComma/FooSemicolon variants exist to ease the implementation of
2429 /// Tree.lastToken()
2430 pub const Tag = enum {
2431 /// sub_list[lhs...rhs]
2432 root,
2433 /// `usingnamespace lhs;`. rhs unused. main_token is `usingnamespace`.
2434 @"usingnamespace",
2435 /// lhs is test name token (must be string literal), if any.
2436 /// rhs is the body node.
2437 test_decl,
2438 /// lhs is the index into extra_data.
2439 /// rhs is the initialization expression, if any.
2440 /// main_token is `var` or `const`.
2441 global_var_decl,
2442 /// `var a: x align(y) = rhs`
2443 /// lhs is the index into extra_data.
2444 /// main_token is `var` or `const`.
2445 local_var_decl,
2446 /// `var a: lhs = rhs`. lhs and rhs may be unused.
2447 /// Can be local or global.
2448 /// main_token is `var` or `const`.
2449 simple_var_decl,
2450 /// `var a align(lhs) = rhs`. lhs and rhs may be unused.
2451 /// Can be local or global.
2452 /// main_token is `var` or `const`.
2453 aligned_var_decl,
2454 /// lhs is the identifier token payload if any,
2455 /// rhs is the deferred expression.
2456 @"errdefer",
2457 /// lhs is unused.
2458 /// rhs is the deferred expression.
2459 @"defer",
2460 /// lhs catch rhs
2461 /// lhs catch |err| rhs
2462 /// main_token is the `catch` keyword.
2463 /// payload is determined by looking at the next token after the `catch` keyword.
2464 @"catch",
2465 /// `lhs.a`. main_token is the dot. rhs is the identifier token index.
2466 field_access,
2467 /// `lhs.?`. main_token is the dot. rhs is the `?` token index.
2468 unwrap_optional,
2469 /// `lhs == rhs`. main_token is op.
2470 equal_equal,
2471 /// `lhs != rhs`. main_token is op.
2472 bang_equal,
2473 /// `lhs < rhs`. main_token is op.
2474 less_than,
2475 /// `lhs > rhs`. main_token is op.
2476 greater_than,
2477 /// `lhs <= rhs`. main_token is op.
2478 less_or_equal,
2479 /// `lhs >= rhs`. main_token is op.
2480 greater_or_equal,
2481 /// `lhs *= rhs`. main_token is op.
2482 assign_mul,
2483 /// `lhs /= rhs`. main_token is op.
2484 assign_div,
2485 /// `lhs *= rhs`. main_token is op.
2486 assign_mod,
2487 /// `lhs += rhs`. main_token is op.
2488 assign_add,
2489 /// `lhs -= rhs`. main_token is op.
2490 assign_sub,
2491 /// `lhs <<= rhs`. main_token is op.
2492 assign_bit_shift_left,
2493 /// `lhs >>= rhs`. main_token is op.
2494 assign_bit_shift_right,
2495 /// `lhs &= rhs`. main_token is op.
2496 assign_bit_and,
2497 /// `lhs ^= rhs`. main_token is op.
2498 assign_bit_xor,
2499 /// `lhs |= rhs`. main_token is op.
2500 assign_bit_or,
2501 /// `lhs *%= rhs`. main_token is op.
2502 assign_mul_wrap,
2503 /// `lhs +%= rhs`. main_token is op.
2504 assign_add_wrap,
2505 /// `lhs -%= rhs`. main_token is op.
2506 assign_sub_wrap,
2507 /// `lhs = rhs`. main_token is op.
2508 assign,
2509 /// `lhs || rhs`. main_token is the `||`.
2510 merge_error_sets,
2511 /// `lhs * rhs`. main_token is the `*`.
2512 mul,
2513 /// `lhs / rhs`. main_token is the `/`.
2514 div,
2515 /// `lhs % rhs`. main_token is the `%`.
2516 mod,
2517 /// `lhs ** rhs`. main_token is the `**`.
2518 array_mult,
2519 /// `lhs *% rhs`. main_token is the `*%`.
2520 mul_wrap,
2521 /// `lhs + rhs`. main_token is the `+`.
2522 add,
2523 /// `lhs - rhs`. main_token is the `-`.
2524 sub,
2525 /// `lhs ++ rhs`. main_token is the `++`.
2526 array_cat,
2527 /// `lhs +% rhs`. main_token is the `+%`.
2528 add_wrap,
2529 /// `lhs -% rhs`. main_token is the `-%`.
2530 sub_wrap,
2531 /// `lhs << rhs`. main_token is the `<<`.
2532 bit_shift_left,
2533 /// `lhs >> rhs`. main_token is the `>>`.
2534 bit_shift_right,
2535 /// `lhs & rhs`. main_token is the `&`.
2536 bit_and,
2537 /// `lhs ^ rhs`. main_token is the `^`.
2538 bit_xor,
2539 /// `lhs | rhs`. main_token is the `|`.
2540 bit_or,
2541 /// `lhs orelse rhs`. main_token is the `orelse`.
2542 @"orelse",
2543 /// `lhs and rhs`. main_token is the `and`.
2544 bool_and,
2545 /// `lhs or rhs`. main_token is the `or`.
2546 bool_or,
2547 /// `op lhs`. rhs unused. main_token is op.
2548 bool_not,
2549 /// `op lhs`. rhs unused. main_token is op.
2550 negation,
2551 /// `op lhs`. rhs unused. main_token is op.
2552 bit_not,
2553 /// `op lhs`. rhs unused. main_token is op.
2554 negation_wrap,
2555 /// `op lhs`. rhs unused. main_token is op.
2556 address_of,
2557 /// `op lhs`. rhs unused. main_token is op.
2558 @"try",
2559 /// `op lhs`. rhs unused. main_token is op.
2560 @"await",
2561 /// `?lhs`. rhs unused. main_token is the `?`.
2562 optional_type,
2563 /// `[lhs]rhs`.
2564 array_type,
2565 /// `[lhs:a]b`. `ArrayTypeSentinel[rhs]`.
2566 array_type_sentinel,
2567 /// `[*]align(lhs) rhs`. lhs can be omitted.
2568 /// `*align(lhs) rhs`. lhs can be omitted.
2569 /// `[]rhs`.
2570 /// main_token is the asterisk if a pointer or the lbracket if a slice
2571 /// main_token might be a ** token, which is shared with a parent/child
2572 /// pointer type and may require special handling.
2573 ptr_type_aligned,
2574 /// `[*:lhs]rhs`. lhs can be omitted.
2575 /// `*rhs`.
2576 /// `[:lhs]rhs`.
2577 /// main_token is the asterisk if a pointer or the lbracket if a slice
2578 /// main_token might be a ** token, which is shared with a parent/child
2579 /// pointer type and may require special handling.
2580 ptr_type_sentinel,
2581 /// lhs is index into ptr_type. rhs is the element type expression.
2582 /// main_token is the asterisk if a pointer or the lbracket if a slice
2583 /// main_token might be a ** token, which is shared with a parent/child
2584 /// pointer type and may require special handling.
2585 ptr_type,
2586 /// lhs is index into ptr_type_bit_range. rhs is the element type expression.
2587 /// main_token is the asterisk if a pointer or the lbracket if a slice
2588 /// main_token might be a ** token, which is shared with a parent/child
2589 /// pointer type and may require special handling.
2590 ptr_type_bit_range,
2591 /// `lhs[rhs..]`
2592 /// main_token is the lbracket.
2593 slice_open,
2594 /// `lhs[b..c]`. rhs is index into Slice
2595 /// main_token is the lbracket.
2596 slice,
2597 /// `lhs[b..c :d]`. rhs is index into SliceSentinel
2598 /// main_token is the lbracket.
2599 slice_sentinel,
2600 /// `lhs.*`. rhs is unused.
2601 deref,
2602 /// `lhs[rhs]`.
2603 array_access,
2604 /// `lhs{rhs}`. rhs can be omitted.
2605 array_init_one,
2606 /// `lhs{rhs,}`. rhs can *not* be omitted
2607 array_init_one_comma,
2608 /// `.{lhs, rhs}`. lhs and rhs can be omitted.
2609 array_init_dot_two,
2610 /// Same as `array_init_dot_two` except there is known to be a trailing comma
2611 /// before the final rbrace.
2612 array_init_dot_two_comma,
2613 /// `.{a, b}`. `sub_list[lhs..rhs]`.
2614 array_init_dot,
2615 /// Same as `array_init_dot` except there is known to be a trailing comma
2616 /// before the final rbrace.
2617 array_init_dot_comma,
2618 /// `lhs{a, b}`. `sub_range_list[rhs]`. lhs can be omitted which means `.{a, b}`.
2619 array_init,
2620 /// Same as `array_init` except there is known to be a trailing comma
2621 /// before the final rbrace.
2622 array_init_comma,
2623 /// `lhs{.a = rhs}`. rhs can be omitted making it empty.
2624 /// main_token is the lbrace.
2625 struct_init_one,
2626 /// `lhs{.a = rhs,}`. rhs can *not* be omitted.
2627 /// main_token is the lbrace.
2628 struct_init_one_comma,
2629 /// `.{.a = lhs, .b = rhs}`. lhs and rhs can be omitted.
2630 /// main_token is the lbrace.
2631 /// No trailing comma before the rbrace.
2632 struct_init_dot_two,
2633 /// Same as `struct_init_dot_two` except there is known to be a trailing comma
2634 /// before the final rbrace.
2635 struct_init_dot_two_comma,
2636 /// `.{.a = b, .c = d}`. `sub_list[lhs..rhs]`.
2637 /// main_token is the lbrace.
2638 struct_init_dot,
2639 /// Same as `struct_init_dot` except there is known to be a trailing comma
2640 /// before the final rbrace.
2641 struct_init_dot_comma,
2642 /// `lhs{.a = b, .c = d}`. `sub_range_list[rhs]`.
2643 /// lhs can be omitted which means `.{.a = b, .c = d}`.
2644 /// main_token is the lbrace.
2645 struct_init,
2646 /// Same as `struct_init` except there is known to be a trailing comma
2647 /// before the final rbrace.
2648 struct_init_comma,
2649 /// `lhs(rhs)`. rhs can be omitted.
2650 /// main_token is the lparen.
2651 call_one,
2652 /// `lhs(rhs,)`. rhs can be omitted.
2653 /// main_token is the lparen.
2654 call_one_comma,
2655 /// `async lhs(rhs)`. rhs can be omitted.
2656 async_call_one,
2657 /// `async lhs(rhs,)`.
2658 async_call_one_comma,
2659 /// `lhs(a, b, c)`. `SubRange[rhs]`.
2660 /// main_token is the `(`.
2661 call,
2662 /// `lhs(a, b, c,)`. `SubRange[rhs]`.
2663 /// main_token is the `(`.
2664 call_comma,
2665 /// `async lhs(a, b, c)`. `SubRange[rhs]`.
2666 /// main_token is the `(`.
2667 async_call,
2668 /// `async lhs(a, b, c,)`. `SubRange[rhs]`.
2669 /// main_token is the `(`.
2670 async_call_comma,
2671 /// `switch(lhs) {}`. `SubRange[rhs]`.
2672 @"switch",
2673 /// Same as switch except there is known to be a trailing comma
2674 /// before the final rbrace
2675 switch_comma,
2676 /// `lhs => rhs`. If lhs is omitted it means `else`.
2677 /// main_token is the `=>`
2678 switch_case_one,
2679 /// `a, b, c => rhs`. `SubRange[lhs]`.
2680 /// main_token is the `=>`
2681 switch_case,
2682 /// `lhs...rhs`.
2683 switch_range,
2684 /// `while (lhs) rhs`.
2685 /// `while (lhs) |x| rhs`.
2686 while_simple,
2687 /// `while (lhs) : (a) b`. `WhileCont[rhs]`.
2688 /// `while (lhs) : (a) b`. `WhileCont[rhs]`.
2689 while_cont,
2690 /// `while (lhs) : (a) b else c`. `While[rhs]`.
2691 /// `while (lhs) |x| : (a) b else c`. `While[rhs]`.
2692 /// `while (lhs) |x| : (a) b else |y| c`. `While[rhs]`.
2693 @"while",
2694 /// `for (lhs) rhs`.
2695 for_simple,
2696 /// `for (lhs) a else b`. `if_list[rhs]`.
2697 @"for",
2698 /// `if (lhs) rhs`.
2699 /// `if (lhs) |a| rhs`.
2700 if_simple,
2701 /// `if (lhs) a else b`. `If[rhs]`.
2702 /// `if (lhs) |x| a else b`. `If[rhs]`.
2703 /// `if (lhs) |x| a else |y| b`. `If[rhs]`.
2704 @"if",
2705 /// `suspend lhs`. lhs can be omitted. rhs is unused.
2706 @"suspend",
2707 /// `resume lhs`. rhs is unused.
2708 @"resume",
2709 /// `continue`. lhs is token index of label if any. rhs is unused.
2710 @"continue",
2711 /// `break :lhs rhs`
2712 /// both lhs and rhs may be omitted.
2713 @"break",
2714 /// `return lhs`. lhs can be omitted. rhs is unused.
2715 @"return",
2716 /// `fn(a: lhs) rhs`. lhs can be omitted.
2717 /// anytype and ... parameters are omitted from the AST tree.
2718 /// main_token is the `fn` keyword.
2719 /// extern function declarations use this tag.
2720 fn_proto_simple,
2721 /// `fn(a: b, c: d) rhs`. `sub_range_list[lhs]`.
2722 /// anytype and ... parameters are omitted from the AST tree.
2723 /// main_token is the `fn` keyword.
2724 /// extern function declarations use this tag.
2725 fn_proto_multi,
2726 /// `fn(a: b) rhs linksection(e) callconv(f)`. `FnProtoOne[lhs]`.
2727 /// zero or one parameters.
2728 /// anytype and ... parameters are omitted from the AST tree.
2729 /// main_token is the `fn` keyword.
2730 /// extern function declarations use this tag.
2731 fn_proto_one,
2732 /// `fn(a: b, c: d) rhs linksection(e) callconv(f)`. `FnProto[lhs]`.
2733 /// anytype and ... parameters are omitted from the AST tree.
2734 /// main_token is the `fn` keyword.
2735 /// extern function declarations use this tag.
2736 fn_proto,
2737 /// lhs is the fn_proto.
2738 /// rhs is the function body block.
2739 /// Note that extern function declarations use the fn_proto tags rather
2740 /// than this one.
2741 fn_decl,
2742 /// `anyframe->rhs`. main_token is `anyframe`. `lhs` is arrow token index.
2743 anyframe_type,
2744 /// Both lhs and rhs unused.
2745 anyframe_literal,
2746 /// Both lhs and rhs unused.
2747 char_literal,
2748 /// Both lhs and rhs unused.
2749 integer_literal,
2750 /// Both lhs and rhs unused.
2751 float_literal,
2752 /// Both lhs and rhs unused.
2753 unreachable_literal,
2754 /// Both lhs and rhs unused.
2755 /// Most identifiers will not have explicit AST nodes, however for expressions
2756 /// which could be one of many different kinds of AST nodes, there will be an
2757 /// identifier AST node for it.
2758 identifier,
2759 /// lhs is the dot token index, rhs unused, main_token is the identifier.
2760 enum_literal,
2761 /// main_token is the string literal token
2762 /// Both lhs and rhs unused.
2763 string_literal,
2764 /// main_token is the first token index (redundant with lhs)
2765 /// lhs is the first token index; rhs is the last token index.
2766 /// Could be a series of multiline_string_literal_line tokens, or a single
2767 /// string_literal token.
2768 multiline_string_literal,
2769 /// `(lhs)`. main_token is the `(`; rhs is the token index of the `)`.
2770 grouped_expression,
2771 /// `@a(lhs, rhs)`. lhs and rhs may be omitted.
2772 /// main_token is the builtin token.
2773 builtin_call_two,
2774 /// Same as builtin_call_two but there is known to be a trailing comma before the rparen.
2775 builtin_call_two_comma,
2776 /// `@a(b, c)`. `sub_list[lhs..rhs]`.
2777 /// main_token is the builtin token.
2778 builtin_call,
2779 /// Same as builtin_call but there is known to be a trailing comma before the rparen.
2780 builtin_call_comma,
2781 /// `error{a, b}`.
2782 /// rhs is the rbrace, lhs is unused.
2783 error_set_decl,
2784 /// `struct {}`, `union {}`, `opaque {}`, `enum {}`. `extra_data[lhs..rhs]`.
2785 /// main_token is `struct`, `union`, `opaque`, `enum` keyword.
2786 container_decl,
2787 /// Same as ContainerDecl but there is known to be a trailing comma
2788 /// or semicolon before the rbrace.
2789 container_decl_trailing,
2790 /// `struct {lhs, rhs}`, `union {lhs, rhs}`, `opaque {lhs, rhs}`, `enum {lhs, rhs}`.
2791 /// lhs or rhs can be omitted.
2792 /// main_token is `struct`, `union`, `opaque`, `enum` keyword.
2793 container_decl_two,
2794 /// Same as ContainerDeclTwo except there is known to be a trailing comma
2795 /// or semicolon before the rbrace.
2796 container_decl_two_trailing,
2797 /// `union(lhs)` / `enum(lhs)`. `SubRange[rhs]`.
2798 container_decl_arg,
2799 /// Same as container_decl_arg but there is known to be a trailing
2800 /// comma or semicolon before the rbrace.
2801 container_decl_arg_trailing,
2802 /// `union(enum) {}`. `sub_list[lhs..rhs]`.
2803 /// Note that tagged unions with explicitly provided enums are represented
2804 /// by `container_decl_arg`.
2805 tagged_union,
2806 /// Same as tagged_union but there is known to be a trailing comma
2807 /// or semicolon before the rbrace.
2808 tagged_union_trailing,
2809 /// `union(enum) {lhs, rhs}`. lhs or rhs may be omitted.
2810 /// Note that tagged unions with explicitly provided enums are represented
2811 /// by `container_decl_arg`.
2812 tagged_union_two,
2813 /// Same as tagged_union_two but there is known to be a trailing comma
2814 /// or semicolon before the rbrace.
2815 tagged_union_two_trailing,
2816 /// `union(enum(lhs)) {}`. `SubRange[rhs]`.
2817 tagged_union_enum_tag,
2818 /// Same as tagged_union_enum_tag but there is known to be a trailing comma
2819 /// or semicolon before the rbrace.
2820 tagged_union_enum_tag_trailing,
2821 /// `a: lhs = rhs,`. lhs and rhs can be omitted.
2822 /// main_token is the field name identifier.
2823 /// lastToken() does not include the possible trailing comma.
2824 container_field_init,
2825 /// `a: lhs align(rhs),`. rhs can be omitted.
2826 /// main_token is the field name identifier.
2827 /// lastToken() does not include the possible trailing comma.
2828 container_field_align,
2829 /// `a: lhs align(c) = d,`. `container_field_list[rhs]`.
2830 /// main_token is the field name identifier.
2831 /// lastToken() does not include the possible trailing comma.
2832 container_field,
2833 /// `anytype`. both lhs and rhs unused.
2834 /// Used by `ContainerField`.
2835 @"anytype",
2836 /// `comptime lhs`. rhs unused.
2837 @"comptime",
2838 /// `nosuspend lhs`. rhs unused.
2839 @"nosuspend",
2840 /// `{lhs rhs}`. rhs or lhs can be omitted.
2841 /// main_token points at the lbrace.
2842 block_two,
2843 /// Same as block_two but there is known to be a semicolon before the rbrace.
2844 block_two_semicolon,
2845 /// `{}`. `sub_list[lhs..rhs]`.
2846 /// main_token points at the lbrace.
2847 block,
2848 /// Same as block but there is known to be a semicolon before the rbrace.
2849 block_semicolon,
2850 /// `asm(lhs)`. rhs is the token index of the rparen.
2851 asm_simple,
2852 /// `asm(lhs, a)`. `Asm[rhs]`.
2853 @"asm",
2854 /// `[a] "b" (c)`. lhs is 0, rhs is token index of the rparen.
2855 /// `[a] "b" (-> lhs)`. rhs is token index of the rparen.
2856 /// main_token is `a`.
2857 asm_output,
2858 /// `[a] "b" (lhs)`. rhs is token index of the rparen.
2859 /// main_token is `a`.
2860 asm_input,
2861 /// `error.a`. lhs is token index of `.`. rhs is token index of `a`.
2862 error_value,
2863 /// `lhs!rhs`. main_token is the `!`.
2864 error_union,
2865
2866 pub fn isContainerField(tag: Tag) bool {
2867 return switch (tag) {
2868 .container_field_init,
2869 .container_field_align,
2870 .container_field,
2871 => true,
2872
2873 else => false,
2874 };
2875 }
2876 };
2877
2878 pub const Data = struct {
2879 lhs: Index,
2880 rhs: Index,
2881 };
2882
2883 pub const LocalVarDecl = struct {
2884 type_node: Index,
2885 align_node: Index,
2886 };
2887
2888 pub const ArrayTypeSentinel = struct {
2889 elem_type: Index,
2890 sentinel: Index,
2891 };
2892
2893 pub const PtrType = struct {
2894 sentinel: Index,
2895 align_node: Index,
2896 };
2897
2898 pub const PtrTypeBitRange = struct {
2899 sentinel: Index,
2900 align_node: Index,
2901 bit_range_start: Index,
2902 bit_range_end: Index,
2903 };
2904
2905 pub const SubRange = struct {
2906 /// Index into sub_list.
2907 start: Index,
2908 /// Index into sub_list.
2909 end: Index,
2910 };
2911
2912 pub const If = struct {
2913 then_expr: Index,
2914 else_expr: Index,
2915 };
2916
2917 pub const ContainerField = struct {
2918 value_expr: Index,
2919 align_expr: Index,
2920 };
2921
2922 pub const GlobalVarDecl = struct {
2923 type_node: Index,
2924 align_node: Index,
2925 section_node: Index,
2926 };
2927
2928 pub const Slice = struct {
2929 start: Index,
2930 end: Index,
2931 };
2932
2933 pub const SliceSentinel = struct {
2934 start: Index,
2935 /// May be 0 if the slice is "open"
2936 end: Index,
2937 sentinel: Index,
2938 };
2939
2940 pub const While = struct {
2941 cont_expr: Index,
2942 then_expr: Index,
2943 else_expr: Index,
2944 };
2945
2946 pub const WhileCont = struct {
2947 cont_expr: Index,
2948 then_expr: Index,
2949 };
2950
2951 pub const FnProtoOne = struct {
2952 /// Populated if there is exactly 1 parameter. Otherwise there are 0 parameters.
2953 param: Index,
2954 /// Populated if align(A) is present.
2955 align_expr: Index,
2956 /// Populated if linksection(A) is present.
2957 section_expr: Index,
2958 /// Populated if callconv(A) is present.
2959 callconv_expr: Index,
2960 };
2961
2962 pub const FnProto = struct {
2963 params_start: Index,
2964 params_end: Index,
2965 /// Populated if align(A) is present.
2966 align_expr: Index,
2967 /// Populated if linksection(A) is present.
2968 section_expr: Index,
2969 /// Populated if callconv(A) is present.
2970 callconv_expr: Index,
2971 };
2972
2973 pub const Asm = struct {
2974 items_start: Index,
2975 items_end: Index,
2976 /// Needed to make lastToken() work.
2977 rparen: TokenIndex,
2978 };
2979};
lib/std/zig/ast.zig deleted-2978
......@@ -1,2978 +0,0 @@
1const std = @import("../std.zig");
2const assert = std.debug.assert;
3const testing = std.testing;
4const mem = std.mem;
5const Token = std.zig.Token;
6
7pub const TokenIndex = u32;
8pub const ByteOffset = u32;
9
10pub const TokenList = std.MultiArrayList(struct {
11 tag: Token.Tag,
12 start: ByteOffset,
13});
14pub const NodeList = std.MultiArrayList(Node);
15
16pub const Tree = struct {
17 /// Reference to externally-owned data.
18 source: [:0]const u8,
19
20 tokens: TokenList.Slice,
21 /// The root AST node is assumed to be index 0. Since there can be no
22 /// references to the root node, this means 0 is available to indicate null.
23 nodes: NodeList.Slice,
24 extra_data: []Node.Index,
25
26 errors: []const Error,
27
28 pub const Location = struct {
29 line: usize,
30 column: usize,
31 line_start: usize,
32 line_end: usize,
33 };
34
35 pub fn deinit(tree: *Tree, gpa: *mem.Allocator) void {
36 tree.tokens.deinit(gpa);
37 tree.nodes.deinit(gpa);
38 gpa.free(tree.extra_data);
39 gpa.free(tree.errors);
40 tree.* = undefined;
41 }
42
43 pub const RenderError = error{
44 /// Ran out of memory allocating call stack frames to complete rendering, or
45 /// ran out of memory allocating space in the output buffer.
46 OutOfMemory,
47 };
48
49 /// `gpa` is used for allocating the resulting formatted source code, as well as
50 /// for allocating extra stack memory if needed, because this function utilizes recursion.
51 /// Note: that's not actually true yet, see https://github.com/ziglang/zig/issues/1006.
52 /// Caller owns the returned slice of bytes, allocated with `gpa`.
53 pub fn render(tree: Tree, gpa: *mem.Allocator) RenderError![]u8 {
54 var buffer = std.ArrayList(u8).init(gpa);
55 defer buffer.deinit();
56
57 try tree.renderToArrayList(&buffer);
58 return buffer.toOwnedSlice();
59 }
60
61 pub fn renderToArrayList(tree: Tree, buffer: *std.ArrayList(u8)) RenderError!void {
62 return @import("./render.zig").renderTree(buffer, tree);
63 }
64
65 pub fn tokenLocation(self: Tree, start_offset: ByteOffset, token_index: TokenIndex) Location {
66 var loc = Location{
67 .line = 0,
68 .column = 0,
69 .line_start = start_offset,
70 .line_end = self.source.len,
71 };
72 const token_start = self.tokens.items(.start)[token_index];
73 for (self.source[start_offset..]) |c, i| {
74 if (i + start_offset == token_start) {
75 loc.line_end = i + start_offset;
76 while (loc.line_end < self.source.len and self.source[loc.line_end] != '\n') {
77 loc.line_end += 1;
78 }
79 return loc;
80 }
81 if (c == '\n') {
82 loc.line += 1;
83 loc.column = 0;
84 loc.line_start = i + 1;
85 } else {
86 loc.column += 1;
87 }
88 }
89 return loc;
90 }
91
92 pub fn tokenSlice(tree: Tree, token_index: TokenIndex) []const u8 {
93 const token_starts = tree.tokens.items(.start);
94 const token_tags = tree.tokens.items(.tag);
95 const token_tag = token_tags[token_index];
96
97 // Many tokens can be determined entirely by their tag.
98 if (token_tag.lexeme()) |lexeme| {
99 return lexeme;
100 }
101
102 // For some tokens, re-tokenization is needed to find the end.
103 var tokenizer: std.zig.Tokenizer = .{
104 .buffer = tree.source,
105 .index = token_starts[token_index],
106 .pending_invalid_token = null,
107 };
108 const token = tokenizer.next();
109 assert(token.tag == token_tag);
110 return tree.source[token.loc.start..token.loc.end];
111 }
112
113 pub fn extraData(tree: Tree, index: usize, comptime T: type) T {
114 const fields = std.meta.fields(T);
115 var result: T = undefined;
116 inline for (fields) |field, i| {
117 comptime assert(field.field_type == Node.Index);
118 @field(result, field.name) = tree.extra_data[index + i];
119 }
120 return result;
121 }
122
123 pub fn rootDecls(tree: Tree) []const Node.Index {
124 // Root is always index 0.
125 const nodes_data = tree.nodes.items(.data);
126 return tree.extra_data[nodes_data[0].lhs..nodes_data[0].rhs];
127 }
128
129 pub fn renderError(tree: Tree, parse_error: Error, stream: anytype) !void {
130 const token_tags = tree.tokens.items(.tag);
131 switch (parse_error.tag) {
132 .asterisk_after_ptr_deref => {
133 // Note that the token will point at the `.*` but ideally the source
134 // location would point to the `*` after the `.*`.
135 return stream.writeAll("'.*' cannot be followed by '*'. Are you missing a space?");
136 },
137 .decl_between_fields => {
138 return stream.writeAll("declarations are not allowed between container fields");
139 },
140 .expected_block => {
141 return stream.print("expected block or field, found '{s}'", .{
142 token_tags[parse_error.token].symbol(),
143 });
144 },
145 .expected_block_or_assignment => {
146 return stream.print("expected block or assignment, found '{s}'", .{
147 token_tags[parse_error.token].symbol(),
148 });
149 },
150 .expected_block_or_expr => {
151 return stream.print("expected block or expression, found '{s}'", .{
152 token_tags[parse_error.token].symbol(),
153 });
154 },
155 .expected_block_or_field => {
156 return stream.print("expected block or field, found '{s}'", .{
157 token_tags[parse_error.token].symbol(),
158 });
159 },
160 .expected_container_members => {
161 return stream.print("expected test, comptime, var decl, or container field, found '{s}'", .{
162 token_tags[parse_error.token].symbol(),
163 });
164 },
165 .expected_expr => {
166 return stream.print("expected expression, found '{s}'", .{
167 token_tags[parse_error.token].symbol(),
168 });
169 },
170 .expected_expr_or_assignment => {
171 return stream.print("expected expression or assignment, found '{s}'", .{
172 token_tags[parse_error.token].symbol(),
173 });
174 },
175 .expected_fn => {
176 return stream.print("expected function, found '{s}'", .{
177 token_tags[parse_error.token].symbol(),
178 });
179 },
180 .expected_inlinable => {
181 return stream.print("expected 'while' or 'for', found '{s}'", .{
182 token_tags[parse_error.token].symbol(),
183 });
184 },
185 .expected_labelable => {
186 return stream.print("expected 'while', 'for', 'inline', 'suspend', or '{{', found '{s}'", .{
187 token_tags[parse_error.token].symbol(),
188 });
189 },
190 .expected_param_list => {
191 return stream.print("expected parameter list, found '{s}'", .{
192 token_tags[parse_error.token].symbol(),
193 });
194 },
195 .expected_prefix_expr => {
196 return stream.print("expected prefix expression, found '{s}'", .{
197 token_tags[parse_error.token].symbol(),
198 });
199 },
200 .expected_primary_type_expr => {
201 return stream.print("expected primary type expression, found '{s}'", .{
202 token_tags[parse_error.token].symbol(),
203 });
204 },
205 .expected_pub_item => {
206 return stream.writeAll("expected function or variable declaration after pub");
207 },
208 .expected_return_type => {
209 return stream.print("expected return type expression, found '{s}'", .{
210 token_tags[parse_error.token].symbol(),
211 });
212 },
213 .expected_semi_or_else => {
214 return stream.print("expected ';' or 'else', found '{s}'", .{
215 token_tags[parse_error.token].symbol(),
216 });
217 },
218 .expected_semi_or_lbrace => {
219 return stream.print("expected ';' or '{{', found '{s}'", .{
220 token_tags[parse_error.token].symbol(),
221 });
222 },
223 .expected_statement => {
224 return stream.print("expected statement, found '{s}'", .{
225 token_tags[parse_error.token].symbol(),
226 });
227 },
228 .expected_string_literal => {
229 return stream.print("expected string literal, found '{s}'", .{
230 token_tags[parse_error.token].symbol(),
231 });
232 },
233 .expected_suffix_op => {
234 return stream.print("expected pointer dereference, optional unwrap, or field access, found '{s}'", .{
235 token_tags[parse_error.token].symbol(),
236 });
237 },
238 .expected_type_expr => {
239 return stream.print("expected type expression, found '{s}'", .{
240 token_tags[parse_error.token].symbol(),
241 });
242 },
243 .expected_var_decl => {
244 return stream.print("expected variable declaration, found '{s}'", .{
245 token_tags[parse_error.token].symbol(),
246 });
247 },
248 .expected_var_decl_or_fn => {
249 return stream.print("expected variable declaration or function, found '{s}'", .{
250 token_tags[parse_error.token].symbol(),
251 });
252 },
253 .expected_loop_payload => {
254 return stream.print("expected loop payload, found '{s}'", .{
255 token_tags[parse_error.token].symbol(),
256 });
257 },
258 .expected_container => {
259 return stream.print("expected a struct, enum or union, found '{s}'", .{
260 token_tags[parse_error.token].symbol(),
261 });
262 },
263 .extra_align_qualifier => {
264 return stream.writeAll("extra align qualifier");
265 },
266 .extra_allowzero_qualifier => {
267 return stream.writeAll("extra allowzero qualifier");
268 },
269 .extra_const_qualifier => {
270 return stream.writeAll("extra const qualifier");
271 },
272 .extra_volatile_qualifier => {
273 return stream.writeAll("extra volatile qualifier");
274 },
275 .ptr_mod_on_array_child_type => {
276 return stream.print("pointer modifier '{s}' not allowed on array child type", .{
277 token_tags[parse_error.token].symbol(),
278 });
279 },
280 .invalid_bit_range => {
281 return stream.writeAll("bit range not allowed on slices and arrays");
282 },
283 .invalid_token => {
284 return stream.print("invalid token: '{s}'", .{
285 token_tags[parse_error.token].symbol(),
286 });
287 },
288 .same_line_doc_comment => {
289 return stream.writeAll("same line documentation comment");
290 },
291 .unattached_doc_comment => {
292 return stream.writeAll("unattached documentation comment");
293 },
294 .varargs_nonfinal => {
295 return stream.writeAll("function prototype has parameter after varargs");
296 },
297
298 .expected_token => {
299 const found_tag = token_tags[parse_error.token];
300 const expected_symbol = parse_error.extra.expected_tag.symbol();
301 switch (found_tag) {
302 .invalid => return stream.print("expected '{s}', found invalid bytes", .{
303 expected_symbol,
304 }),
305 else => return stream.print("expected '{s}', found '{s}'", .{
306 expected_symbol, found_tag.symbol(),
307 }),
308 }
309 },
310 }
311 }
312
313 pub fn firstToken(tree: Tree, node: Node.Index) TokenIndex {
314 const tags = tree.nodes.items(.tag);
315 const datas = tree.nodes.items(.data);
316 const main_tokens = tree.nodes.items(.main_token);
317 const token_tags = tree.tokens.items(.tag);
318 var end_offset: TokenIndex = 0;
319 var n = node;
320 while (true) switch (tags[n]) {
321 .root => return 0,
322
323 .test_decl,
324 .@"errdefer",
325 .@"defer",
326 .bool_not,
327 .negation,
328 .bit_not,
329 .negation_wrap,
330 .address_of,
331 .@"try",
332 .@"await",
333 .optional_type,
334 .@"switch",
335 .switch_comma,
336 .if_simple,
337 .@"if",
338 .@"suspend",
339 .@"resume",
340 .@"continue",
341 .@"break",
342 .@"return",
343 .anyframe_type,
344 .identifier,
345 .anyframe_literal,
346 .char_literal,
347 .integer_literal,
348 .float_literal,
349 .unreachable_literal,
350 .string_literal,
351 .multiline_string_literal,
352 .grouped_expression,
353 .builtin_call_two,
354 .builtin_call_two_comma,
355 .builtin_call,
356 .builtin_call_comma,
357 .error_set_decl,
358 .@"anytype",
359 .@"comptime",
360 .@"nosuspend",
361 .asm_simple,
362 .@"asm",
363 .array_type,
364 .array_type_sentinel,
365 .error_value,
366 => return main_tokens[n] - end_offset,
367
368 .array_init_dot,
369 .array_init_dot_comma,
370 .array_init_dot_two,
371 .array_init_dot_two_comma,
372 .struct_init_dot,
373 .struct_init_dot_comma,
374 .struct_init_dot_two,
375 .struct_init_dot_two_comma,
376 .enum_literal,
377 => return main_tokens[n] - 1 - end_offset,
378
379 .@"catch",
380 .field_access,
381 .unwrap_optional,
382 .equal_equal,
383 .bang_equal,
384 .less_than,
385 .greater_than,
386 .less_or_equal,
387 .greater_or_equal,
388 .assign_mul,
389 .assign_div,
390 .assign_mod,
391 .assign_add,
392 .assign_sub,
393 .assign_bit_shift_left,
394 .assign_bit_shift_right,
395 .assign_bit_and,
396 .assign_bit_xor,
397 .assign_bit_or,
398 .assign_mul_wrap,
399 .assign_add_wrap,
400 .assign_sub_wrap,
401 .assign,
402 .merge_error_sets,
403 .mul,
404 .div,
405 .mod,
406 .array_mult,
407 .mul_wrap,
408 .add,
409 .sub,
410 .array_cat,
411 .add_wrap,
412 .sub_wrap,
413 .bit_shift_left,
414 .bit_shift_right,
415 .bit_and,
416 .bit_xor,
417 .bit_or,
418 .@"orelse",
419 .bool_and,
420 .bool_or,
421 .slice_open,
422 .slice,
423 .slice_sentinel,
424 .deref,
425 .array_access,
426 .array_init_one,
427 .array_init_one_comma,
428 .array_init,
429 .array_init_comma,
430 .struct_init_one,
431 .struct_init_one_comma,
432 .struct_init,
433 .struct_init_comma,
434 .call_one,
435 .call_one_comma,
436 .call,
437 .call_comma,
438 .switch_range,
439 .error_union,
440 => n = datas[n].lhs,
441
442 .fn_decl,
443 .fn_proto_simple,
444 .fn_proto_multi,
445 .fn_proto_one,
446 .fn_proto,
447 => {
448 var i = main_tokens[n]; // fn token
449 while (i > 0) {
450 i -= 1;
451 switch (token_tags[i]) {
452 .keyword_extern,
453 .keyword_export,
454 .keyword_pub,
455 .keyword_inline,
456 .keyword_noinline,
457 .string_literal,
458 => continue,
459
460 else => return i + 1 - end_offset,
461 }
462 }
463 return i - end_offset;
464 },
465
466 .@"usingnamespace" => {
467 const main_token = main_tokens[n];
468 if (main_token > 0 and token_tags[main_token - 1] == .keyword_pub) {
469 end_offset += 1;
470 }
471 return main_token - end_offset;
472 },
473
474 .async_call_one,
475 .async_call_one_comma,
476 .async_call,
477 .async_call_comma,
478 => {
479 end_offset += 1; // async token
480 n = datas[n].lhs;
481 },
482
483 .container_field_init,
484 .container_field_align,
485 .container_field,
486 => {
487 const name_token = main_tokens[n];
488 if (name_token > 0 and token_tags[name_token - 1] == .keyword_comptime) {
489 end_offset += 1;
490 }
491 return name_token - end_offset;
492 },
493
494 .global_var_decl,
495 .local_var_decl,
496 .simple_var_decl,
497 .aligned_var_decl,
498 => {
499 var i = main_tokens[n]; // mut token
500 while (i > 0) {
501 i -= 1;
502 switch (token_tags[i]) {
503 .keyword_extern,
504 .keyword_export,
505 .keyword_comptime,
506 .keyword_pub,
507 .keyword_threadlocal,
508 .string_literal,
509 => continue,
510
511 else => return i + 1 - end_offset,
512 }
513 }
514 return i - end_offset;
515 },
516
517 .block,
518 .block_semicolon,
519 .block_two,
520 .block_two_semicolon,
521 => {
522 // Look for a label.
523 const lbrace = main_tokens[n];
524 if (token_tags[lbrace - 1] == .colon and
525 token_tags[lbrace - 2] == .identifier)
526 {
527 end_offset += 2;
528 }
529 return lbrace - end_offset;
530 },
531
532 .container_decl,
533 .container_decl_trailing,
534 .container_decl_two,
535 .container_decl_two_trailing,
536 .container_decl_arg,
537 .container_decl_arg_trailing,
538 .tagged_union,
539 .tagged_union_trailing,
540 .tagged_union_two,
541 .tagged_union_two_trailing,
542 .tagged_union_enum_tag,
543 .tagged_union_enum_tag_trailing,
544 => {
545 const main_token = main_tokens[n];
546 switch (token_tags[main_token - 1]) {
547 .keyword_packed, .keyword_extern => end_offset += 1,
548 else => {},
549 }
550 return main_token - end_offset;
551 },
552
553 .ptr_type_aligned,
554 .ptr_type_sentinel,
555 .ptr_type,
556 .ptr_type_bit_range,
557 => {
558 const main_token = main_tokens[n];
559 return switch (token_tags[main_token]) {
560 .asterisk,
561 .asterisk_asterisk,
562 => switch (token_tags[main_token - 1]) {
563 .l_bracket => main_token - 1,
564 else => main_token,
565 },
566 .l_bracket => main_token,
567 else => unreachable,
568 } - end_offset;
569 },
570
571 .switch_case_one => {
572 if (datas[n].lhs == 0) {
573 return main_tokens[n] - 1 - end_offset; // else token
574 } else {
575 n = datas[n].lhs;
576 }
577 },
578 .switch_case => {
579 const extra = tree.extraData(datas[n].lhs, Node.SubRange);
580 assert(extra.end - extra.start > 0);
581 n = tree.extra_data[extra.start];
582 },
583
584 .asm_output, .asm_input => {
585 assert(token_tags[main_tokens[n] - 1] == .l_bracket);
586 return main_tokens[n] - 1 - end_offset;
587 },
588
589 .while_simple,
590 .while_cont,
591 .@"while",
592 .for_simple,
593 .@"for",
594 => {
595 // Look for a label and inline.
596 const main_token = main_tokens[n];
597 var result = main_token;
598 if (token_tags[result - 1] == .keyword_inline) {
599 result -= 1;
600 }
601 if (token_tags[result - 1] == .colon) {
602 result -= 2;
603 }
604 return result - end_offset;
605 },
606 };
607 }
608
609 pub fn lastToken(tree: Tree, node: Node.Index) TokenIndex {
610 const tags = tree.nodes.items(.tag);
611 const datas = tree.nodes.items(.data);
612 const main_tokens = tree.nodes.items(.main_token);
613 const token_starts = tree.tokens.items(.start);
614 const token_tags = tree.tokens.items(.tag);
615 var n = node;
616 var end_offset: TokenIndex = 0;
617 while (true) switch (tags[n]) {
618 .root => return @intCast(TokenIndex, tree.tokens.len - 1),
619
620 .@"usingnamespace",
621 .bool_not,
622 .negation,
623 .bit_not,
624 .negation_wrap,
625 .address_of,
626 .@"try",
627 .@"await",
628 .optional_type,
629 .@"resume",
630 .@"nosuspend",
631 .@"comptime",
632 => n = datas[n].lhs,
633
634 .test_decl,
635 .@"errdefer",
636 .@"defer",
637 .@"catch",
638 .equal_equal,
639 .bang_equal,
640 .less_than,
641 .greater_than,
642 .less_or_equal,
643 .greater_or_equal,
644 .assign_mul,
645 .assign_div,
646 .assign_mod,
647 .assign_add,
648 .assign_sub,
649 .assign_bit_shift_left,
650 .assign_bit_shift_right,
651 .assign_bit_and,
652 .assign_bit_xor,
653 .assign_bit_or,
654 .assign_mul_wrap,
655 .assign_add_wrap,
656 .assign_sub_wrap,
657 .assign,
658 .merge_error_sets,
659 .mul,
660 .div,
661 .mod,
662 .array_mult,
663 .mul_wrap,
664 .add,
665 .sub,
666 .array_cat,
667 .add_wrap,
668 .sub_wrap,
669 .bit_shift_left,
670 .bit_shift_right,
671 .bit_and,
672 .bit_xor,
673 .bit_or,
674 .@"orelse",
675 .bool_and,
676 .bool_or,
677 .anyframe_type,
678 .error_union,
679 .if_simple,
680 .while_simple,
681 .for_simple,
682 .fn_proto_simple,
683 .fn_proto_multi,
684 .ptr_type_aligned,
685 .ptr_type_sentinel,
686 .ptr_type,
687 .ptr_type_bit_range,
688 .array_type,
689 .switch_case_one,
690 .switch_case,
691 .switch_range,
692 => n = datas[n].rhs,
693
694 .field_access,
695 .unwrap_optional,
696 .grouped_expression,
697 .multiline_string_literal,
698 .error_set_decl,
699 .asm_simple,
700 .asm_output,
701 .asm_input,
702 .error_value,
703 => return datas[n].rhs + end_offset,
704
705 .@"anytype",
706 .anyframe_literal,
707 .char_literal,
708 .integer_literal,
709 .float_literal,
710 .unreachable_literal,
711 .identifier,
712 .deref,
713 .enum_literal,
714 .string_literal,
715 => return main_tokens[n] + end_offset,
716
717 .@"return" => if (datas[n].lhs != 0) {
718 n = datas[n].lhs;
719 } else {
720 return main_tokens[n] + end_offset;
721 },
722
723 .call, .async_call => {
724 end_offset += 1; // for the rparen
725 const params = tree.extraData(datas[n].rhs, Node.SubRange);
726 if (params.end - params.start == 0) {
727 return main_tokens[n] + end_offset;
728 }
729 n = tree.extra_data[params.end - 1]; // last parameter
730 },
731 .tagged_union_enum_tag => {
732 const members = tree.extraData(datas[n].rhs, Node.SubRange);
733 if (members.end - members.start == 0) {
734 end_offset += 4; // for the rparen + rparen + lbrace + rbrace
735 n = datas[n].lhs;
736 } else {
737 end_offset += 1; // for the rbrace
738 n = tree.extra_data[members.end - 1]; // last parameter
739 }
740 },
741 .call_comma,
742 .async_call_comma,
743 .tagged_union_enum_tag_trailing,
744 => {
745 end_offset += 2; // for the comma/semicolon + rparen/rbrace
746 const params = tree.extraData(datas[n].rhs, Node.SubRange);
747 assert(params.end > params.start);
748 n = tree.extra_data[params.end - 1]; // last parameter
749 },
750 .@"switch" => {
751 const cases = tree.extraData(datas[n].rhs, Node.SubRange);
752 if (cases.end - cases.start == 0) {
753 end_offset += 3; // rparen, lbrace, rbrace
754 n = datas[n].lhs; // condition expression
755 } else {
756 end_offset += 1; // for the rbrace
757 n = tree.extra_data[cases.end - 1]; // last case
758 }
759 },
760 .container_decl_arg => {
761 const members = tree.extraData(datas[n].rhs, Node.SubRange);
762 if (members.end - members.start == 0) {
763 end_offset += 3; // for the rparen + lbrace + rbrace
764 n = datas[n].lhs;
765 } else {
766 end_offset += 1; // for the rbrace
767 n = tree.extra_data[members.end - 1]; // last parameter
768 }
769 },
770 .@"asm" => {
771 const extra = tree.extraData(datas[n].rhs, Node.Asm);
772 return extra.rparen + end_offset;
773 },
774 .array_init,
775 .struct_init,
776 => {
777 const elements = tree.extraData(datas[n].rhs, Node.SubRange);
778 assert(elements.end - elements.start > 0);
779 end_offset += 1; // for the rbrace
780 n = tree.extra_data[elements.end - 1]; // last element
781 },
782 .array_init_comma,
783 .struct_init_comma,
784 .container_decl_arg_trailing,
785 .switch_comma,
786 => {
787 const members = tree.extraData(datas[n].rhs, Node.SubRange);
788 assert(members.end - members.start > 0);
789 end_offset += 2; // for the comma + rbrace
790 n = tree.extra_data[members.end - 1]; // last parameter
791 },
792 .array_init_dot,
793 .struct_init_dot,
794 .block,
795 .container_decl,
796 .tagged_union,
797 .builtin_call,
798 => {
799 assert(datas[n].rhs - datas[n].lhs > 0);
800 end_offset += 1; // for the rbrace
801 n = tree.extra_data[datas[n].rhs - 1]; // last statement
802 },
803 .array_init_dot_comma,
804 .struct_init_dot_comma,
805 .block_semicolon,
806 .container_decl_trailing,
807 .tagged_union_trailing,
808 .builtin_call_comma,
809 => {
810 assert(datas[n].rhs - datas[n].lhs > 0);
811 end_offset += 2; // for the comma/semicolon + rbrace/rparen
812 n = tree.extra_data[datas[n].rhs - 1]; // last member
813 },
814 .call_one,
815 .async_call_one,
816 .array_access,
817 => {
818 end_offset += 1; // for the rparen/rbracket
819 if (datas[n].rhs == 0) {
820 return main_tokens[n] + end_offset;
821 }
822 n = datas[n].rhs;
823 },
824 .array_init_dot_two,
825 .block_two,
826 .builtin_call_two,
827 .struct_init_dot_two,
828 .container_decl_two,
829 .tagged_union_two,
830 => {
831 if (datas[n].rhs != 0) {
832 end_offset += 1; // for the rparen/rbrace
833 n = datas[n].rhs;
834 } else if (datas[n].lhs != 0) {
835 end_offset += 1; // for the rparen/rbrace
836 n = datas[n].lhs;
837 } else {
838 switch (tags[n]) {
839 .array_init_dot_two,
840 .block_two,
841 .struct_init_dot_two,
842 => end_offset += 1, // rbrace
843 .builtin_call_two => end_offset += 2, // lparen/lbrace + rparen/rbrace
844 .container_decl_two => {
845 var i: u32 = 2; // lbrace + rbrace
846 while (token_tags[main_tokens[n] + i] == .container_doc_comment) i += 1;
847 end_offset += i;
848 },
849 .tagged_union_two => {
850 var i: u32 = 5; // (enum) {}
851 while (token_tags[main_tokens[n] + i] == .container_doc_comment) i += 1;
852 end_offset += i;
853 },
854 else => unreachable,
855 }
856 return main_tokens[n] + end_offset;
857 }
858 },
859 .array_init_dot_two_comma,
860 .builtin_call_two_comma,
861 .block_two_semicolon,
862 .struct_init_dot_two_comma,
863 .container_decl_two_trailing,
864 .tagged_union_two_trailing,
865 => {
866 end_offset += 2; // for the comma/semicolon + rbrace/rparen
867 if (datas[n].rhs != 0) {
868 n = datas[n].rhs;
869 } else if (datas[n].lhs != 0) {
870 n = datas[n].lhs;
871 } else {
872 unreachable;
873 }
874 },
875 .simple_var_decl => {
876 if (datas[n].rhs != 0) {
877 n = datas[n].rhs;
878 } else if (datas[n].lhs != 0) {
879 n = datas[n].lhs;
880 } else {
881 end_offset += 1; // from mut token to name
882 return main_tokens[n] + end_offset;
883 }
884 },
885 .aligned_var_decl => {
886 if (datas[n].rhs != 0) {
887 n = datas[n].rhs;
888 } else if (datas[n].lhs != 0) {
889 end_offset += 1; // for the rparen
890 n = datas[n].lhs;
891 } else {
892 end_offset += 1; // from mut token to name
893 return main_tokens[n] + end_offset;
894 }
895 },
896 .global_var_decl => {
897 if (datas[n].rhs != 0) {
898 n = datas[n].rhs;
899 } else {
900 const extra = tree.extraData(datas[n].lhs, Node.GlobalVarDecl);
901 if (extra.section_node != 0) {
902 end_offset += 1; // for the rparen
903 n = extra.section_node;
904 } else if (extra.align_node != 0) {
905 end_offset += 1; // for the rparen
906 n = extra.align_node;
907 } else if (extra.type_node != 0) {
908 n = extra.type_node;
909 } else {
910 end_offset += 1; // from mut token to name
911 return main_tokens[n] + end_offset;
912 }
913 }
914 },
915 .local_var_decl => {
916 if (datas[n].rhs != 0) {
917 n = datas[n].rhs;
918 } else {
919 const extra = tree.extraData(datas[n].lhs, Node.LocalVarDecl);
920 if (extra.align_node != 0) {
921 end_offset += 1; // for the rparen
922 n = extra.align_node;
923 } else if (extra.type_node != 0) {
924 n = extra.type_node;
925 } else {
926 end_offset += 1; // from mut token to name
927 return main_tokens[n] + end_offset;
928 }
929 }
930 },
931 .container_field_init => {
932 if (datas[n].rhs != 0) {
933 n = datas[n].rhs;
934 } else if (datas[n].lhs != 0) {
935 n = datas[n].lhs;
936 } else {
937 return main_tokens[n] + end_offset;
938 }
939 },
940 .container_field_align => {
941 if (datas[n].rhs != 0) {
942 end_offset += 1; // for the rparen
943 n = datas[n].rhs;
944 } else if (datas[n].lhs != 0) {
945 n = datas[n].lhs;
946 } else {
947 return main_tokens[n] + end_offset;
948 }
949 },
950 .container_field => {
951 const extra = tree.extraData(datas[n].rhs, Node.ContainerField);
952 if (extra.value_expr != 0) {
953 n = extra.value_expr;
954 } else if (extra.align_expr != 0) {
955 end_offset += 1; // for the rparen
956 n = extra.align_expr;
957 } else if (datas[n].lhs != 0) {
958 n = datas[n].lhs;
959 } else {
960 return main_tokens[n] + end_offset;
961 }
962 },
963
964 .array_init_one,
965 .struct_init_one,
966 => {
967 end_offset += 1; // rbrace
968 if (datas[n].rhs == 0) {
969 return main_tokens[n] + end_offset;
970 } else {
971 n = datas[n].rhs;
972 }
973 },
974 .slice_open,
975 .call_one_comma,
976 .async_call_one_comma,
977 .array_init_one_comma,
978 .struct_init_one_comma,
979 => {
980 end_offset += 2; // ellipsis2 + rbracket, or comma + rparen
981 n = datas[n].rhs;
982 assert(n != 0);
983 },
984 .slice => {
985 const extra = tree.extraData(datas[n].rhs, Node.Slice);
986 assert(extra.end != 0); // should have used slice_open
987 end_offset += 1; // rbracket
988 n = extra.end;
989 },
990 .slice_sentinel => {
991 const extra = tree.extraData(datas[n].rhs, Node.SliceSentinel);
992 assert(extra.sentinel != 0); // should have used slice
993 end_offset += 1; // rbracket
994 n = extra.sentinel;
995 },
996
997 .@"continue" => {
998 if (datas[n].lhs != 0) {
999 return datas[n].lhs + end_offset;
1000 } else {
1001 return main_tokens[n] + end_offset;
1002 }
1003 },
1004 .@"break" => {
1005 if (datas[n].rhs != 0) {
1006 n = datas[n].rhs;
1007 } else if (datas[n].lhs != 0) {
1008 return datas[n].lhs + end_offset;
1009 } else {
1010 return main_tokens[n] + end_offset;
1011 }
1012 },
1013 .fn_decl => {
1014 if (datas[n].rhs != 0) {
1015 n = datas[n].rhs;
1016 } else {
1017 n = datas[n].lhs;
1018 }
1019 },
1020 .fn_proto_one => {
1021 const extra = tree.extraData(datas[n].lhs, Node.FnProtoOne);
1022 // linksection, callconv, align can appear in any order, so we
1023 // find the last one here.
1024 var max_node: Node.Index = datas[n].rhs;
1025 var max_start = token_starts[main_tokens[max_node]];
1026 var max_offset: TokenIndex = 0;
1027 if (extra.align_expr != 0) {
1028 const start = token_starts[main_tokens[extra.align_expr]];
1029 if (start > max_start) {
1030 max_node = extra.align_expr;
1031 max_start = start;
1032 max_offset = 1; // for the rparen
1033 }
1034 }
1035 if (extra.section_expr != 0) {
1036 const start = token_starts[main_tokens[extra.section_expr]];
1037 if (start > max_start) {
1038 max_node = extra.section_expr;
1039 max_start = start;
1040 max_offset = 1; // for the rparen
1041 }
1042 }
1043 if (extra.callconv_expr != 0) {
1044 const start = token_starts[main_tokens[extra.callconv_expr]];
1045 if (start > max_start) {
1046 max_node = extra.callconv_expr;
1047 max_start = start;
1048 max_offset = 1; // for the rparen
1049 }
1050 }
1051 n = max_node;
1052 end_offset += max_offset;
1053 },
1054 .fn_proto => {
1055 const extra = tree.extraData(datas[n].lhs, Node.FnProto);
1056 // linksection, callconv, align can appear in any order, so we
1057 // find the last one here.
1058 var max_node: Node.Index = datas[n].rhs;
1059 var max_start = token_starts[main_tokens[max_node]];
1060 var max_offset: TokenIndex = 0;
1061 if (extra.align_expr != 0) {
1062 const start = token_starts[main_tokens[extra.align_expr]];
1063 if (start > max_start) {
1064 max_node = extra.align_expr;
1065 max_start = start;
1066 max_offset = 1; // for the rparen
1067 }
1068 }
1069 if (extra.section_expr != 0) {
1070 const start = token_starts[main_tokens[extra.section_expr]];
1071 if (start > max_start) {
1072 max_node = extra.section_expr;
1073 max_start = start;
1074 max_offset = 1; // for the rparen
1075 }
1076 }
1077 if (extra.callconv_expr != 0) {
1078 const start = token_starts[main_tokens[extra.callconv_expr]];
1079 if (start > max_start) {
1080 max_node = extra.callconv_expr;
1081 max_start = start;
1082 max_offset = 1; // for the rparen
1083 }
1084 }
1085 n = max_node;
1086 end_offset += max_offset;
1087 },
1088 .while_cont => {
1089 const extra = tree.extraData(datas[n].rhs, Node.WhileCont);
1090 assert(extra.then_expr != 0);
1091 n = extra.then_expr;
1092 },
1093 .@"while" => {
1094 const extra = tree.extraData(datas[n].rhs, Node.While);
1095 assert(extra.else_expr != 0);
1096 n = extra.else_expr;
1097 },
1098 .@"if", .@"for" => {
1099 const extra = tree.extraData(datas[n].rhs, Node.If);
1100 assert(extra.else_expr != 0);
1101 n = extra.else_expr;
1102 },
1103 .@"suspend" => {
1104 if (datas[n].lhs != 0) {
1105 n = datas[n].lhs;
1106 } else {
1107 return main_tokens[n] + end_offset;
1108 }
1109 },
1110 .array_type_sentinel => {
1111 const extra = tree.extraData(datas[n].rhs, Node.ArrayTypeSentinel);
1112 n = extra.elem_type;
1113 },
1114 };
1115 }
1116
1117 pub fn tokensOnSameLine(tree: Tree, token1: TokenIndex, token2: TokenIndex) bool {
1118 const token_starts = tree.tokens.items(.start);
1119 const source = tree.source[token_starts[token1]..token_starts[token2]];
1120 return mem.indexOfScalar(u8, source, '\n') == null;
1121 }
1122
1123 pub fn getNodeSource(tree: Tree, node: Node.Index) []const u8 {
1124 const token_starts = tree.tokens.items(.start);
1125 const first_token = tree.firstToken(node);
1126 const last_token = tree.lastToken(node);
1127 const start = token_starts[first_token];
1128 const end = token_starts[last_token] + tree.tokenSlice(last_token).len;
1129 return tree.source[start..end];
1130 }
1131
1132 pub fn globalVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
1133 assert(tree.nodes.items(.tag)[node] == .global_var_decl);
1134 const data = tree.nodes.items(.data)[node];
1135 const extra = tree.extraData(data.lhs, Node.GlobalVarDecl);
1136 return tree.fullVarDecl(.{
1137 .type_node = extra.type_node,
1138 .align_node = extra.align_node,
1139 .section_node = extra.section_node,
1140 .init_node = data.rhs,
1141 .mut_token = tree.nodes.items(.main_token)[node],
1142 });
1143 }
1144
1145 pub fn localVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
1146 assert(tree.nodes.items(.tag)[node] == .local_var_decl);
1147 const data = tree.nodes.items(.data)[node];
1148 const extra = tree.extraData(data.lhs, Node.LocalVarDecl);
1149 return tree.fullVarDecl(.{
1150 .type_node = extra.type_node,
1151 .align_node = extra.align_node,
1152 .section_node = 0,
1153 .init_node = data.rhs,
1154 .mut_token = tree.nodes.items(.main_token)[node],
1155 });
1156 }
1157
1158 pub fn simpleVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
1159 assert(tree.nodes.items(.tag)[node] == .simple_var_decl);
1160 const data = tree.nodes.items(.data)[node];
1161 return tree.fullVarDecl(.{
1162 .type_node = data.lhs,
1163 .align_node = 0,
1164 .section_node = 0,
1165 .init_node = data.rhs,
1166 .mut_token = tree.nodes.items(.main_token)[node],
1167 });
1168 }
1169
1170 pub fn alignedVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
1171 assert(tree.nodes.items(.tag)[node] == .aligned_var_decl);
1172 const data = tree.nodes.items(.data)[node];
1173 return tree.fullVarDecl(.{
1174 .type_node = 0,
1175 .align_node = data.lhs,
1176 .section_node = 0,
1177 .init_node = data.rhs,
1178 .mut_token = tree.nodes.items(.main_token)[node],
1179 });
1180 }
1181
1182 pub fn ifSimple(tree: Tree, node: Node.Index) full.If {
1183 assert(tree.nodes.items(.tag)[node] == .if_simple);
1184 const data = tree.nodes.items(.data)[node];
1185 return tree.fullIf(.{
1186 .cond_expr = data.lhs,
1187 .then_expr = data.rhs,
1188 .else_expr = 0,
1189 .if_token = tree.nodes.items(.main_token)[node],
1190 });
1191 }
1192
1193 pub fn ifFull(tree: Tree, node: Node.Index) full.If {
1194 assert(tree.nodes.items(.tag)[node] == .@"if");
1195 const data = tree.nodes.items(.data)[node];
1196 const extra = tree.extraData(data.rhs, Node.If);
1197 return tree.fullIf(.{
1198 .cond_expr = data.lhs,
1199 .then_expr = extra.then_expr,
1200 .else_expr = extra.else_expr,
1201 .if_token = tree.nodes.items(.main_token)[node],
1202 });
1203 }
1204
1205 pub fn containerField(tree: Tree, node: Node.Index) full.ContainerField {
1206 assert(tree.nodes.items(.tag)[node] == .container_field);
1207 const data = tree.nodes.items(.data)[node];
1208 const extra = tree.extraData(data.rhs, Node.ContainerField);
1209 return tree.fullContainerField(.{
1210 .name_token = tree.nodes.items(.main_token)[node],
1211 .type_expr = data.lhs,
1212 .value_expr = extra.value_expr,
1213 .align_expr = extra.align_expr,
1214 });
1215 }
1216
1217 pub fn containerFieldInit(tree: Tree, node: Node.Index) full.ContainerField {
1218 assert(tree.nodes.items(.tag)[node] == .container_field_init);
1219 const data = tree.nodes.items(.data)[node];
1220 return tree.fullContainerField(.{
1221 .name_token = tree.nodes.items(.main_token)[node],
1222 .type_expr = data.lhs,
1223 .value_expr = data.rhs,
1224 .align_expr = 0,
1225 });
1226 }
1227
1228 pub fn containerFieldAlign(tree: Tree, node: Node.Index) full.ContainerField {
1229 assert(tree.nodes.items(.tag)[node] == .container_field_align);
1230 const data = tree.nodes.items(.data)[node];
1231 return tree.fullContainerField(.{
1232 .name_token = tree.nodes.items(.main_token)[node],
1233 .type_expr = data.lhs,
1234 .value_expr = 0,
1235 .align_expr = data.rhs,
1236 });
1237 }
1238
1239 pub fn fnProtoSimple(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.FnProto {
1240 assert(tree.nodes.items(.tag)[node] == .fn_proto_simple);
1241 const data = tree.nodes.items(.data)[node];
1242 buffer[0] = data.lhs;
1243 const params = if (data.lhs == 0) buffer[0..0] else buffer[0..1];
1244 return tree.fullFnProto(.{
1245 .proto_node = node,
1246 .fn_token = tree.nodes.items(.main_token)[node],
1247 .return_type = data.rhs,
1248 .params = params,
1249 .align_expr = 0,
1250 .section_expr = 0,
1251 .callconv_expr = 0,
1252 });
1253 }
1254
1255 pub fn fnProtoMulti(tree: Tree, node: Node.Index) full.FnProto {
1256 assert(tree.nodes.items(.tag)[node] == .fn_proto_multi);
1257 const data = tree.nodes.items(.data)[node];
1258 const params_range = tree.extraData(data.lhs, Node.SubRange);
1259 const params = tree.extra_data[params_range.start..params_range.end];
1260 return tree.fullFnProto(.{
1261 .proto_node = node,
1262 .fn_token = tree.nodes.items(.main_token)[node],
1263 .return_type = data.rhs,
1264 .params = params,
1265 .align_expr = 0,
1266 .section_expr = 0,
1267 .callconv_expr = 0,
1268 });
1269 }
1270
1271 pub fn fnProtoOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.FnProto {
1272 assert(tree.nodes.items(.tag)[node] == .fn_proto_one);
1273 const data = tree.nodes.items(.data)[node];
1274 const extra = tree.extraData(data.lhs, Node.FnProtoOne);
1275 buffer[0] = extra.param;
1276 const params = if (extra.param == 0) buffer[0..0] else buffer[0..1];
1277 return tree.fullFnProto(.{
1278 .proto_node = node,
1279 .fn_token = tree.nodes.items(.main_token)[node],
1280 .return_type = data.rhs,
1281 .params = params,
1282 .align_expr = extra.align_expr,
1283 .section_expr = extra.section_expr,
1284 .callconv_expr = extra.callconv_expr,
1285 });
1286 }
1287
1288 pub fn fnProto(tree: Tree, node: Node.Index) full.FnProto {
1289 assert(tree.nodes.items(.tag)[node] == .fn_proto);
1290 const data = tree.nodes.items(.data)[node];
1291 const extra = tree.extraData(data.lhs, Node.FnProto);
1292 const params = tree.extra_data[extra.params_start..extra.params_end];
1293 return tree.fullFnProto(.{
1294 .proto_node = node,
1295 .fn_token = tree.nodes.items(.main_token)[node],
1296 .return_type = data.rhs,
1297 .params = params,
1298 .align_expr = extra.align_expr,
1299 .section_expr = extra.section_expr,
1300 .callconv_expr = extra.callconv_expr,
1301 });
1302 }
1303
1304 pub fn structInitOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.StructInit {
1305 assert(tree.nodes.items(.tag)[node] == .struct_init_one or
1306 tree.nodes.items(.tag)[node] == .struct_init_one_comma);
1307 const data = tree.nodes.items(.data)[node];
1308 buffer[0] = data.rhs;
1309 const fields = if (data.rhs == 0) buffer[0..0] else buffer[0..1];
1310 return tree.fullStructInit(.{
1311 .lbrace = tree.nodes.items(.main_token)[node],
1312 .fields = fields,
1313 .type_expr = data.lhs,
1314 });
1315 }
1316
1317 pub fn structInitDotTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.StructInit {
1318 assert(tree.nodes.items(.tag)[node] == .struct_init_dot_two or
1319 tree.nodes.items(.tag)[node] == .struct_init_dot_two_comma);
1320 const data = tree.nodes.items(.data)[node];
1321 buffer.* = .{ data.lhs, data.rhs };
1322 const fields = if (data.rhs != 0)
1323 buffer[0..2]
1324 else if (data.lhs != 0)
1325 buffer[0..1]
1326 else
1327 buffer[0..0];
1328 return tree.fullStructInit(.{
1329 .lbrace = tree.nodes.items(.main_token)[node],
1330 .fields = fields,
1331 .type_expr = 0,
1332 });
1333 }
1334
1335 pub fn structInitDot(tree: Tree, node: Node.Index) full.StructInit {
1336 assert(tree.nodes.items(.tag)[node] == .struct_init_dot or
1337 tree.nodes.items(.tag)[node] == .struct_init_dot_comma);
1338 const data = tree.nodes.items(.data)[node];
1339 return tree.fullStructInit(.{
1340 .lbrace = tree.nodes.items(.main_token)[node],
1341 .fields = tree.extra_data[data.lhs..data.rhs],
1342 .type_expr = 0,
1343 });
1344 }
1345
1346 pub fn structInit(tree: Tree, node: Node.Index) full.StructInit {
1347 assert(tree.nodes.items(.tag)[node] == .struct_init or
1348 tree.nodes.items(.tag)[node] == .struct_init_comma);
1349 const data = tree.nodes.items(.data)[node];
1350 const fields_range = tree.extraData(data.rhs, Node.SubRange);
1351 return tree.fullStructInit(.{
1352 .lbrace = tree.nodes.items(.main_token)[node],
1353 .fields = tree.extra_data[fields_range.start..fields_range.end],
1354 .type_expr = data.lhs,
1355 });
1356 }
1357
1358 pub fn arrayInitOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.ArrayInit {
1359 assert(tree.nodes.items(.tag)[node] == .array_init_one or
1360 tree.nodes.items(.tag)[node] == .array_init_one_comma);
1361 const data = tree.nodes.items(.data)[node];
1362 buffer[0] = data.rhs;
1363 const elements = if (data.rhs == 0) buffer[0..0] else buffer[0..1];
1364 return .{
1365 .ast = .{
1366 .lbrace = tree.nodes.items(.main_token)[node],
1367 .elements = elements,
1368 .type_expr = data.lhs,
1369 },
1370 };
1371 }
1372
1373 pub fn arrayInitDotTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.ArrayInit {
1374 assert(tree.nodes.items(.tag)[node] == .array_init_dot_two or
1375 tree.nodes.items(.tag)[node] == .array_init_dot_two_comma);
1376 const data = tree.nodes.items(.data)[node];
1377 buffer.* = .{ data.lhs, data.rhs };
1378 const elements = if (data.rhs != 0)
1379 buffer[0..2]
1380 else if (data.lhs != 0)
1381 buffer[0..1]
1382 else
1383 buffer[0..0];
1384 return .{
1385 .ast = .{
1386 .lbrace = tree.nodes.items(.main_token)[node],
1387 .elements = elements,
1388 .type_expr = 0,
1389 },
1390 };
1391 }
1392
1393 pub fn arrayInitDot(tree: Tree, node: Node.Index) full.ArrayInit {
1394 assert(tree.nodes.items(.tag)[node] == .array_init_dot or
1395 tree.nodes.items(.tag)[node] == .array_init_dot_comma);
1396 const data = tree.nodes.items(.data)[node];
1397 return .{
1398 .ast = .{
1399 .lbrace = tree.nodes.items(.main_token)[node],
1400 .elements = tree.extra_data[data.lhs..data.rhs],
1401 .type_expr = 0,
1402 },
1403 };
1404 }
1405
1406 pub fn arrayInit(tree: Tree, node: Node.Index) full.ArrayInit {
1407 assert(tree.nodes.items(.tag)[node] == .array_init or
1408 tree.nodes.items(.tag)[node] == .array_init_comma);
1409 const data = tree.nodes.items(.data)[node];
1410 const elem_range = tree.extraData(data.rhs, Node.SubRange);
1411 return .{
1412 .ast = .{
1413 .lbrace = tree.nodes.items(.main_token)[node],
1414 .elements = tree.extra_data[elem_range.start..elem_range.end],
1415 .type_expr = data.lhs,
1416 },
1417 };
1418 }
1419
1420 pub fn arrayType(tree: Tree, node: Node.Index) full.ArrayType {
1421 assert(tree.nodes.items(.tag)[node] == .array_type);
1422 const data = tree.nodes.items(.data)[node];
1423 return .{
1424 .ast = .{
1425 .lbracket = tree.nodes.items(.main_token)[node],
1426 .elem_count = data.lhs,
1427 .sentinel = 0,
1428 .elem_type = data.rhs,
1429 },
1430 };
1431 }
1432
1433 pub fn arrayTypeSentinel(tree: Tree, node: Node.Index) full.ArrayType {
1434 assert(tree.nodes.items(.tag)[node] == .array_type_sentinel);
1435 const data = tree.nodes.items(.data)[node];
1436 const extra = tree.extraData(data.rhs, Node.ArrayTypeSentinel);
1437 assert(extra.sentinel != 0);
1438 return .{
1439 .ast = .{
1440 .lbracket = tree.nodes.items(.main_token)[node],
1441 .elem_count = data.lhs,
1442 .sentinel = extra.sentinel,
1443 .elem_type = extra.elem_type,
1444 },
1445 };
1446 }
1447
1448 pub fn ptrTypeAligned(tree: Tree, node: Node.Index) full.PtrType {
1449 assert(tree.nodes.items(.tag)[node] == .ptr_type_aligned);
1450 const data = tree.nodes.items(.data)[node];
1451 return tree.fullPtrType(.{
1452 .main_token = tree.nodes.items(.main_token)[node],
1453 .align_node = data.lhs,
1454 .sentinel = 0,
1455 .bit_range_start = 0,
1456 .bit_range_end = 0,
1457 .child_type = data.rhs,
1458 });
1459 }
1460
1461 pub fn ptrTypeSentinel(tree: Tree, node: Node.Index) full.PtrType {
1462 assert(tree.nodes.items(.tag)[node] == .ptr_type_sentinel);
1463 const data = tree.nodes.items(.data)[node];
1464 return tree.fullPtrType(.{
1465 .main_token = tree.nodes.items(.main_token)[node],
1466 .align_node = 0,
1467 .sentinel = data.lhs,
1468 .bit_range_start = 0,
1469 .bit_range_end = 0,
1470 .child_type = data.rhs,
1471 });
1472 }
1473
1474 pub fn ptrType(tree: Tree, node: Node.Index) full.PtrType {
1475 assert(tree.nodes.items(.tag)[node] == .ptr_type);
1476 const data = tree.nodes.items(.data)[node];
1477 const extra = tree.extraData(data.lhs, Node.PtrType);
1478 return tree.fullPtrType(.{
1479 .main_token = tree.nodes.items(.main_token)[node],
1480 .align_node = extra.align_node,
1481 .sentinel = extra.sentinel,
1482 .bit_range_start = 0,
1483 .bit_range_end = 0,
1484 .child_type = data.rhs,
1485 });
1486 }
1487
1488 pub fn ptrTypeBitRange(tree: Tree, node: Node.Index) full.PtrType {
1489 assert(tree.nodes.items(.tag)[node] == .ptr_type_bit_range);
1490 const data = tree.nodes.items(.data)[node];
1491 const extra = tree.extraData(data.lhs, Node.PtrTypeBitRange);
1492 return tree.fullPtrType(.{
1493 .main_token = tree.nodes.items(.main_token)[node],
1494 .align_node = extra.align_node,
1495 .sentinel = extra.sentinel,
1496 .bit_range_start = extra.bit_range_start,
1497 .bit_range_end = extra.bit_range_end,
1498 .child_type = data.rhs,
1499 });
1500 }
1501
1502 pub fn sliceOpen(tree: Tree, node: Node.Index) full.Slice {
1503 assert(tree.nodes.items(.tag)[node] == .slice_open);
1504 const data = tree.nodes.items(.data)[node];
1505 return .{
1506 .ast = .{
1507 .sliced = data.lhs,
1508 .lbracket = tree.nodes.items(.main_token)[node],
1509 .start = data.rhs,
1510 .end = 0,
1511 .sentinel = 0,
1512 },
1513 };
1514 }
1515
1516 pub fn slice(tree: Tree, node: Node.Index) full.Slice {
1517 assert(tree.nodes.items(.tag)[node] == .slice);
1518 const data = tree.nodes.items(.data)[node];
1519 const extra = tree.extraData(data.rhs, Node.Slice);
1520 return .{
1521 .ast = .{
1522 .sliced = data.lhs,
1523 .lbracket = tree.nodes.items(.main_token)[node],
1524 .start = extra.start,
1525 .end = extra.end,
1526 .sentinel = 0,
1527 },
1528 };
1529 }
1530
1531 pub fn sliceSentinel(tree: Tree, node: Node.Index) full.Slice {
1532 assert(tree.nodes.items(.tag)[node] == .slice_sentinel);
1533 const data = tree.nodes.items(.data)[node];
1534 const extra = tree.extraData(data.rhs, Node.SliceSentinel);
1535 return .{
1536 .ast = .{
1537 .sliced = data.lhs,
1538 .lbracket = tree.nodes.items(.main_token)[node],
1539 .start = extra.start,
1540 .end = extra.end,
1541 .sentinel = extra.sentinel,
1542 },
1543 };
1544 }
1545
1546 pub fn containerDeclTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl {
1547 assert(tree.nodes.items(.tag)[node] == .container_decl_two or
1548 tree.nodes.items(.tag)[node] == .container_decl_two_trailing);
1549 const data = tree.nodes.items(.data)[node];
1550 buffer.* = .{ data.lhs, data.rhs };
1551 const members = if (data.rhs != 0)
1552 buffer[0..2]
1553 else if (data.lhs != 0)
1554 buffer[0..1]
1555 else
1556 buffer[0..0];
1557 return tree.fullContainerDecl(.{
1558 .main_token = tree.nodes.items(.main_token)[node],
1559 .enum_token = null,
1560 .members = members,
1561 .arg = 0,
1562 });
1563 }
1564
1565 pub fn containerDecl(tree: Tree, node: Node.Index) full.ContainerDecl {
1566 assert(tree.nodes.items(.tag)[node] == .container_decl or
1567 tree.nodes.items(.tag)[node] == .container_decl_trailing);
1568 const data = tree.nodes.items(.data)[node];
1569 return tree.fullContainerDecl(.{
1570 .main_token = tree.nodes.items(.main_token)[node],
1571 .enum_token = null,
1572 .members = tree.extra_data[data.lhs..data.rhs],
1573 .arg = 0,
1574 });
1575 }
1576
1577 pub fn containerDeclArg(tree: Tree, node: Node.Index) full.ContainerDecl {
1578 assert(tree.nodes.items(.tag)[node] == .container_decl_arg or
1579 tree.nodes.items(.tag)[node] == .container_decl_arg_trailing);
1580 const data = tree.nodes.items(.data)[node];
1581 const members_range = tree.extraData(data.rhs, Node.SubRange);
1582 return tree.fullContainerDecl(.{
1583 .main_token = tree.nodes.items(.main_token)[node],
1584 .enum_token = null,
1585 .members = tree.extra_data[members_range.start..members_range.end],
1586 .arg = data.lhs,
1587 });
1588 }
1589
1590 pub fn taggedUnionTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl {
1591 assert(tree.nodes.items(.tag)[node] == .tagged_union_two or
1592 tree.nodes.items(.tag)[node] == .tagged_union_two_trailing);
1593 const data = tree.nodes.items(.data)[node];
1594 buffer.* = .{ data.lhs, data.rhs };
1595 const members = if (data.rhs != 0)
1596 buffer[0..2]
1597 else if (data.lhs != 0)
1598 buffer[0..1]
1599 else
1600 buffer[0..0];
1601 const main_token = tree.nodes.items(.main_token)[node];
1602 return tree.fullContainerDecl(.{
1603 .main_token = main_token,
1604 .enum_token = main_token + 2, // union lparen enum
1605 .members = members,
1606 .arg = 0,
1607 });
1608 }
1609
1610 pub fn taggedUnion(tree: Tree, node: Node.Index) full.ContainerDecl {
1611 assert(tree.nodes.items(.tag)[node] == .tagged_union or
1612 tree.nodes.items(.tag)[node] == .tagged_union_trailing);
1613 const data = tree.nodes.items(.data)[node];
1614 const main_token = tree.nodes.items(.main_token)[node];
1615 return tree.fullContainerDecl(.{
1616 .main_token = main_token,
1617 .enum_token = main_token + 2, // union lparen enum
1618 .members = tree.extra_data[data.lhs..data.rhs],
1619 .arg = 0,
1620 });
1621 }
1622
1623 pub fn taggedUnionEnumTag(tree: Tree, node: Node.Index) full.ContainerDecl {
1624 assert(tree.nodes.items(.tag)[node] == .tagged_union_enum_tag or
1625 tree.nodes.items(.tag)[node] == .tagged_union_enum_tag_trailing);
1626 const data = tree.nodes.items(.data)[node];
1627 const members_range = tree.extraData(data.rhs, Node.SubRange);
1628 const main_token = tree.nodes.items(.main_token)[node];
1629 return tree.fullContainerDecl(.{
1630 .main_token = main_token,
1631 .enum_token = main_token + 2, // union lparen enum
1632 .members = tree.extra_data[members_range.start..members_range.end],
1633 .arg = data.lhs,
1634 });
1635 }
1636
1637 pub fn switchCaseOne(tree: Tree, node: Node.Index) full.SwitchCase {
1638 const data = &tree.nodes.items(.data)[node];
1639 const values: *[1]Node.Index = &data.lhs;
1640 return tree.fullSwitchCase(.{
1641 .values = if (data.lhs == 0) values[0..0] else values[0..1],
1642 .arrow_token = tree.nodes.items(.main_token)[node],
1643 .target_expr = data.rhs,
1644 });
1645 }
1646
1647 pub fn switchCase(tree: Tree, node: Node.Index) full.SwitchCase {
1648 const data = tree.nodes.items(.data)[node];
1649 const extra = tree.extraData(data.lhs, Node.SubRange);
1650 return tree.fullSwitchCase(.{
1651 .values = tree.extra_data[extra.start..extra.end],
1652 .arrow_token = tree.nodes.items(.main_token)[node],
1653 .target_expr = data.rhs,
1654 });
1655 }
1656
1657 pub fn asmSimple(tree: Tree, node: Node.Index) full.Asm {
1658 const data = tree.nodes.items(.data)[node];
1659 return tree.fullAsm(.{
1660 .asm_token = tree.nodes.items(.main_token)[node],
1661 .template = data.lhs,
1662 .items = &.{},
1663 .rparen = data.rhs,
1664 });
1665 }
1666
1667 pub fn asmFull(tree: Tree, node: Node.Index) full.Asm {
1668 const data = tree.nodes.items(.data)[node];
1669 const extra = tree.extraData(data.rhs, Node.Asm);
1670 return tree.fullAsm(.{
1671 .asm_token = tree.nodes.items(.main_token)[node],
1672 .template = data.lhs,
1673 .items = tree.extra_data[extra.items_start..extra.items_end],
1674 .rparen = extra.rparen,
1675 });
1676 }
1677
1678 pub fn whileSimple(tree: Tree, node: Node.Index) full.While {
1679 const data = tree.nodes.items(.data)[node];
1680 return tree.fullWhile(.{
1681 .while_token = tree.nodes.items(.main_token)[node],
1682 .cond_expr = data.lhs,
1683 .cont_expr = 0,
1684 .then_expr = data.rhs,
1685 .else_expr = 0,
1686 });
1687 }
1688
1689 pub fn whileCont(tree: Tree, node: Node.Index) full.While {
1690 const data = tree.nodes.items(.data)[node];
1691 const extra = tree.extraData(data.rhs, Node.WhileCont);
1692 return tree.fullWhile(.{
1693 .while_token = tree.nodes.items(.main_token)[node],
1694 .cond_expr = data.lhs,
1695 .cont_expr = extra.cont_expr,
1696 .then_expr = extra.then_expr,
1697 .else_expr = 0,
1698 });
1699 }
1700
1701 pub fn whileFull(tree: Tree, node: Node.Index) full.While {
1702 const data = tree.nodes.items(.data)[node];
1703 const extra = tree.extraData(data.rhs, Node.While);
1704 return tree.fullWhile(.{
1705 .while_token = tree.nodes.items(.main_token)[node],
1706 .cond_expr = data.lhs,
1707 .cont_expr = extra.cont_expr,
1708 .then_expr = extra.then_expr,
1709 .else_expr = extra.else_expr,
1710 });
1711 }
1712
1713 pub fn forSimple(tree: Tree, node: Node.Index) full.While {
1714 const data = tree.nodes.items(.data)[node];
1715 return tree.fullWhile(.{
1716 .while_token = tree.nodes.items(.main_token)[node],
1717 .cond_expr = data.lhs,
1718 .cont_expr = 0,
1719 .then_expr = data.rhs,
1720 .else_expr = 0,
1721 });
1722 }
1723
1724 pub fn forFull(tree: Tree, node: Node.Index) full.While {
1725 const data = tree.nodes.items(.data)[node];
1726 const extra = tree.extraData(data.rhs, Node.If);
1727 return tree.fullWhile(.{
1728 .while_token = tree.nodes.items(.main_token)[node],
1729 .cond_expr = data.lhs,
1730 .cont_expr = 0,
1731 .then_expr = extra.then_expr,
1732 .else_expr = extra.else_expr,
1733 });
1734 }
1735
1736 pub fn callOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.Call {
1737 const data = tree.nodes.items(.data)[node];
1738 buffer.* = .{data.rhs};
1739 const params = if (data.rhs != 0) buffer[0..1] else buffer[0..0];
1740 return tree.fullCall(.{
1741 .lparen = tree.nodes.items(.main_token)[node],
1742 .fn_expr = data.lhs,
1743 .params = params,
1744 });
1745 }
1746
1747 pub fn callFull(tree: Tree, node: Node.Index) full.Call {
1748 const data = tree.nodes.items(.data)[node];
1749 const extra = tree.extraData(data.rhs, Node.SubRange);
1750 return tree.fullCall(.{
1751 .lparen = tree.nodes.items(.main_token)[node],
1752 .fn_expr = data.lhs,
1753 .params = tree.extra_data[extra.start..extra.end],
1754 });
1755 }
1756
1757 fn fullVarDecl(tree: Tree, info: full.VarDecl.Ast) full.VarDecl {
1758 const token_tags = tree.tokens.items(.tag);
1759 var result: full.VarDecl = .{
1760 .ast = info,
1761 .visib_token = null,
1762 .extern_export_token = null,
1763 .lib_name = null,
1764 .threadlocal_token = null,
1765 .comptime_token = null,
1766 };
1767 var i = info.mut_token;
1768 while (i > 0) {
1769 i -= 1;
1770 switch (token_tags[i]) {
1771 .keyword_extern, .keyword_export => result.extern_export_token = i,
1772 .keyword_comptime => result.comptime_token = i,
1773 .keyword_pub => result.visib_token = i,
1774 .keyword_threadlocal => result.threadlocal_token = i,
1775 .string_literal => result.lib_name = i,
1776 else => break,
1777 }
1778 }
1779 return result;
1780 }
1781
1782 fn fullIf(tree: Tree, info: full.If.Ast) full.If {
1783 const token_tags = tree.tokens.items(.tag);
1784 var result: full.If = .{
1785 .ast = info,
1786 .payload_token = null,
1787 .error_token = null,
1788 .else_token = undefined,
1789 };
1790 // if (cond_expr) |x|
1791 // ^ ^
1792 const payload_pipe = tree.lastToken(info.cond_expr) + 2;
1793 if (token_tags[payload_pipe] == .pipe) {
1794 result.payload_token = payload_pipe + 1;
1795 }
1796 if (info.else_expr != 0) {
1797 // then_expr else |x|
1798 // ^ ^
1799 result.else_token = tree.lastToken(info.then_expr) + 1;
1800 if (token_tags[result.else_token + 1] == .pipe) {
1801 result.error_token = result.else_token + 2;
1802 }
1803 }
1804 return result;
1805 }
1806
1807 fn fullContainerField(tree: Tree, info: full.ContainerField.Ast) full.ContainerField {
1808 const token_tags = tree.tokens.items(.tag);
1809 var result: full.ContainerField = .{
1810 .ast = info,
1811 .comptime_token = null,
1812 };
1813 // comptime name: type = init,
1814 // ^
1815 if (info.name_token > 0 and token_tags[info.name_token - 1] == .keyword_comptime) {
1816 result.comptime_token = info.name_token - 1;
1817 }
1818 return result;
1819 }
1820
1821 fn fullFnProto(tree: Tree, info: full.FnProto.Ast) full.FnProto {
1822 const token_tags = tree.tokens.items(.tag);
1823 var result: full.FnProto = .{
1824 .ast = info,
1825 .visib_token = null,
1826 .extern_export_inline_token = null,
1827 .lib_name = null,
1828 .name_token = null,
1829 .lparen = undefined,
1830 };
1831 var i = info.fn_token;
1832 while (i > 0) {
1833 i -= 1;
1834 switch (token_tags[i]) {
1835 .keyword_extern,
1836 .keyword_export,
1837 .keyword_inline,
1838 .keyword_noinline,
1839 => result.extern_export_inline_token = i,
1840 .keyword_pub => result.visib_token = i,
1841 .string_literal => result.lib_name = i,
1842 else => break,
1843 }
1844 }
1845 const after_fn_token = info.fn_token + 1;
1846 if (token_tags[after_fn_token] == .identifier) {
1847 result.name_token = after_fn_token;
1848 result.lparen = after_fn_token + 1;
1849 } else {
1850 result.lparen = after_fn_token;
1851 }
1852 assert(token_tags[result.lparen] == .l_paren);
1853
1854 return result;
1855 }
1856
1857 fn fullStructInit(tree: Tree, info: full.StructInit.Ast) full.StructInit {
1858 _ = tree;
1859 var result: full.StructInit = .{
1860 .ast = info,
1861 };
1862 return result;
1863 }
1864
1865 fn fullPtrType(tree: Tree, info: full.PtrType.Ast) full.PtrType {
1866 const token_tags = tree.tokens.items(.tag);
1867 // TODO: looks like stage1 isn't quite smart enough to handle enum
1868 // literals in some places here
1869 const Size = std.builtin.TypeInfo.Pointer.Size;
1870 const size: Size = switch (token_tags[info.main_token]) {
1871 .asterisk,
1872 .asterisk_asterisk,
1873 => switch (token_tags[info.main_token + 1]) {
1874 .r_bracket, .colon => .Many,
1875 .identifier => if (token_tags[info.main_token - 1] == .l_bracket) Size.C else .One,
1876 else => .One,
1877 },
1878 .l_bracket => Size.Slice,
1879 else => unreachable,
1880 };
1881 var result: full.PtrType = .{
1882 .size = size,
1883 .allowzero_token = null,
1884 .const_token = null,
1885 .volatile_token = null,
1886 .ast = info,
1887 };
1888 // We need to be careful that we don't iterate over any sub-expressions
1889 // here while looking for modifiers as that could result in false
1890 // positives. Therefore, start after a sentinel if there is one and
1891 // skip over any align node and bit range nodes.
1892 var i = if (info.sentinel != 0) tree.lastToken(info.sentinel) + 1 else info.main_token;
1893 const end = tree.firstToken(info.child_type);
1894 while (i < end) : (i += 1) {
1895 switch (token_tags[i]) {
1896 .keyword_allowzero => result.allowzero_token = i,
1897 .keyword_const => result.const_token = i,
1898 .keyword_volatile => result.volatile_token = i,
1899 .keyword_align => {
1900 assert(info.align_node != 0);
1901 if (info.bit_range_end != 0) {
1902 assert(info.bit_range_start != 0);
1903 i = tree.lastToken(info.bit_range_end) + 1;
1904 } else {
1905 i = tree.lastToken(info.align_node) + 1;
1906 }
1907 },
1908 else => {},
1909 }
1910 }
1911 return result;
1912 }
1913
1914 fn fullContainerDecl(tree: Tree, info: full.ContainerDecl.Ast) full.ContainerDecl {
1915 const token_tags = tree.tokens.items(.tag);
1916 var result: full.ContainerDecl = .{
1917 .ast = info,
1918 .layout_token = null,
1919 };
1920 switch (token_tags[info.main_token - 1]) {
1921 .keyword_extern, .keyword_packed => result.layout_token = info.main_token - 1,
1922 else => {},
1923 }
1924 return result;
1925 }
1926
1927 fn fullSwitchCase(tree: Tree, info: full.SwitchCase.Ast) full.SwitchCase {
1928 const token_tags = tree.tokens.items(.tag);
1929 var result: full.SwitchCase = .{
1930 .ast = info,
1931 .payload_token = null,
1932 };
1933 if (token_tags[info.arrow_token + 1] == .pipe) {
1934 result.payload_token = info.arrow_token + 2;
1935 }
1936 return result;
1937 }
1938
1939 fn fullAsm(tree: Tree, info: full.Asm.Ast) full.Asm {
1940 const token_tags = tree.tokens.items(.tag);
1941 const node_tags = tree.nodes.items(.tag);
1942 var result: full.Asm = .{
1943 .ast = info,
1944 .volatile_token = null,
1945 .inputs = &.{},
1946 .outputs = &.{},
1947 .first_clobber = null,
1948 };
1949 if (token_tags[info.asm_token + 1] == .keyword_volatile) {
1950 result.volatile_token = info.asm_token + 1;
1951 }
1952 const outputs_end: usize = for (info.items) |item, i| {
1953 switch (node_tags[item]) {
1954 .asm_output => continue,
1955 else => break i,
1956 }
1957 } else info.items.len;
1958
1959 result.outputs = info.items[0..outputs_end];
1960 result.inputs = info.items[outputs_end..];
1961
1962 if (info.items.len == 0) {
1963 // asm ("foo" ::: "a", "b");
1964 const template_token = tree.lastToken(info.template);
1965 if (token_tags[template_token + 1] == .colon and
1966 token_tags[template_token + 2] == .colon and
1967 token_tags[template_token + 3] == .colon and
1968 token_tags[template_token + 4] == .string_literal)
1969 {
1970 result.first_clobber = template_token + 4;
1971 }
1972 } else if (result.inputs.len != 0) {
1973 // asm ("foo" :: [_] "" (y) : "a", "b");
1974 const last_input = result.inputs[result.inputs.len - 1];
1975 const rparen = tree.lastToken(last_input);
1976 var i = rparen + 1;
1977 // Allow a (useless) comma right after the closing parenthesis.
1978 if (token_tags[i] == .comma) i += 1;
1979 if (token_tags[i] == .colon and
1980 token_tags[i + 1] == .string_literal)
1981 {
1982 result.first_clobber = i + 1;
1983 }
1984 } else {
1985 // asm ("foo" : [_] "" (x) :: "a", "b");
1986 const last_output = result.outputs[result.outputs.len - 1];
1987 const rparen = tree.lastToken(last_output);
1988 var i = rparen + 1;
1989 // Allow a (useless) comma right after the closing parenthesis.
1990 if (token_tags[i] == .comma) i += 1;
1991 if (token_tags[i] == .colon and
1992 token_tags[i + 1] == .colon and
1993 token_tags[i + 2] == .string_literal)
1994 {
1995 result.first_clobber = i + 2;
1996 }
1997 }
1998
1999 return result;
2000 }
2001
2002 fn fullWhile(tree: Tree, info: full.While.Ast) full.While {
2003 const token_tags = tree.tokens.items(.tag);
2004 var result: full.While = .{
2005 .ast = info,
2006 .inline_token = null,
2007 .label_token = null,
2008 .payload_token = null,
2009 .else_token = undefined,
2010 .error_token = null,
2011 };
2012 var tok_i = info.while_token - 1;
2013 if (token_tags[tok_i] == .keyword_inline) {
2014 result.inline_token = tok_i;
2015 tok_i -= 1;
2016 }
2017 if (token_tags[tok_i] == .colon and
2018 token_tags[tok_i - 1] == .identifier)
2019 {
2020 result.label_token = tok_i - 1;
2021 }
2022 const last_cond_token = tree.lastToken(info.cond_expr);
2023 if (token_tags[last_cond_token + 2] == .pipe) {
2024 result.payload_token = last_cond_token + 3;
2025 }
2026 if (info.else_expr != 0) {
2027 // then_expr else |x|
2028 // ^ ^
2029 result.else_token = tree.lastToken(info.then_expr) + 1;
2030 if (token_tags[result.else_token + 1] == .pipe) {
2031 result.error_token = result.else_token + 2;
2032 }
2033 }
2034 return result;
2035 }
2036
2037 fn fullCall(tree: Tree, info: full.Call.Ast) full.Call {
2038 const token_tags = tree.tokens.items(.tag);
2039 var result: full.Call = .{
2040 .ast = info,
2041 .async_token = null,
2042 };
2043 const maybe_async_token = tree.firstToken(info.fn_expr) - 1;
2044 if (token_tags[maybe_async_token] == .keyword_async) {
2045 result.async_token = maybe_async_token;
2046 }
2047 return result;
2048 }
2049};
2050
2051/// Fully assembled AST node information.
2052pub const full = struct {
2053 pub const VarDecl = struct {
2054 visib_token: ?TokenIndex,
2055 extern_export_token: ?TokenIndex,
2056 lib_name: ?TokenIndex,
2057 threadlocal_token: ?TokenIndex,
2058 comptime_token: ?TokenIndex,
2059 ast: Ast,
2060
2061 pub const Ast = struct {
2062 mut_token: TokenIndex,
2063 type_node: Node.Index,
2064 align_node: Node.Index,
2065 section_node: Node.Index,
2066 init_node: Node.Index,
2067 };
2068 };
2069
2070 pub const If = struct {
2071 /// Points to the first token after the `|`. Will either be an identifier or
2072 /// a `*` (with an identifier immediately after it).
2073 payload_token: ?TokenIndex,
2074 /// Points to the identifier after the `|`.
2075 error_token: ?TokenIndex,
2076 /// Populated only if else_expr != 0.
2077 else_token: TokenIndex,
2078 ast: Ast,
2079
2080 pub const Ast = struct {
2081 if_token: TokenIndex,
2082 cond_expr: Node.Index,
2083 then_expr: Node.Index,
2084 else_expr: Node.Index,
2085 };
2086 };
2087
2088 pub const While = struct {
2089 ast: Ast,
2090 inline_token: ?TokenIndex,
2091 label_token: ?TokenIndex,
2092 payload_token: ?TokenIndex,
2093 error_token: ?TokenIndex,
2094 /// Populated only if else_expr != 0.
2095 else_token: TokenIndex,
2096
2097 pub const Ast = struct {
2098 while_token: TokenIndex,
2099 cond_expr: Node.Index,
2100 cont_expr: Node.Index,
2101 then_expr: Node.Index,
2102 else_expr: Node.Index,
2103 };
2104 };
2105
2106 pub const ContainerField = struct {
2107 comptime_token: ?TokenIndex,
2108 ast: Ast,
2109
2110 pub const Ast = struct {
2111 name_token: TokenIndex,
2112 type_expr: Node.Index,
2113 value_expr: Node.Index,
2114 align_expr: Node.Index,
2115 };
2116 };
2117
2118 pub const FnProto = struct {
2119 visib_token: ?TokenIndex,
2120 extern_export_inline_token: ?TokenIndex,
2121 lib_name: ?TokenIndex,
2122 name_token: ?TokenIndex,
2123 lparen: TokenIndex,
2124 ast: Ast,
2125
2126 pub const Ast = struct {
2127 proto_node: Node.Index,
2128 fn_token: TokenIndex,
2129 return_type: Node.Index,
2130 params: []const Node.Index,
2131 align_expr: Node.Index,
2132 section_expr: Node.Index,
2133 callconv_expr: Node.Index,
2134 };
2135
2136 pub const Param = struct {
2137 first_doc_comment: ?TokenIndex,
2138 name_token: ?TokenIndex,
2139 comptime_noalias: ?TokenIndex,
2140 anytype_ellipsis3: ?TokenIndex,
2141 type_expr: Node.Index,
2142 };
2143
2144 /// Abstracts over the fact that anytype and ... are not included
2145 /// in the params slice, since they are simple identifiers and
2146 /// not sub-expressions.
2147 pub const Iterator = struct {
2148 tree: *const Tree,
2149 fn_proto: *const FnProto,
2150 param_i: usize,
2151 tok_i: TokenIndex,
2152 tok_flag: bool,
2153
2154 pub fn next(it: *Iterator) ?Param {
2155 const token_tags = it.tree.tokens.items(.tag);
2156 while (true) {
2157 var first_doc_comment: ?TokenIndex = null;
2158 var comptime_noalias: ?TokenIndex = null;
2159 var name_token: ?TokenIndex = null;
2160 if (!it.tok_flag) {
2161 if (it.param_i >= it.fn_proto.ast.params.len) {
2162 return null;
2163 }
2164 const param_type = it.fn_proto.ast.params[it.param_i];
2165 var tok_i = it.tree.firstToken(param_type) - 1;
2166 while (true) : (tok_i -= 1) switch (token_tags[tok_i]) {
2167 .colon => continue,
2168 .identifier => name_token = tok_i,
2169 .doc_comment => first_doc_comment = tok_i,
2170 .keyword_comptime, .keyword_noalias => comptime_noalias = tok_i,
2171 else => break,
2172 };
2173 it.param_i += 1;
2174 it.tok_i = it.tree.lastToken(param_type) + 1;
2175 // Look for anytype and ... params afterwards.
2176 if (token_tags[it.tok_i] == .comma) {
2177 it.tok_i += 1;
2178 }
2179 it.tok_flag = true;
2180 return Param{
2181 .first_doc_comment = first_doc_comment,
2182 .comptime_noalias = comptime_noalias,
2183 .name_token = name_token,
2184 .anytype_ellipsis3 = null,
2185 .type_expr = param_type,
2186 };
2187 }
2188 if (token_tags[it.tok_i] == .comma) {
2189 it.tok_i += 1;
2190 }
2191 if (token_tags[it.tok_i] == .r_paren) {
2192 return null;
2193 }
2194 if (token_tags[it.tok_i] == .doc_comment) {
2195 first_doc_comment = it.tok_i;
2196 while (token_tags[it.tok_i] == .doc_comment) {
2197 it.tok_i += 1;
2198 }
2199 }
2200 switch (token_tags[it.tok_i]) {
2201 .ellipsis3 => {
2202 it.tok_flag = false; // Next iteration should return null.
2203 return Param{
2204 .first_doc_comment = first_doc_comment,
2205 .comptime_noalias = null,
2206 .name_token = null,
2207 .anytype_ellipsis3 = it.tok_i,
2208 .type_expr = 0,
2209 };
2210 },
2211 .keyword_noalias, .keyword_comptime => {
2212 comptime_noalias = it.tok_i;
2213 it.tok_i += 1;
2214 },
2215 else => {},
2216 }
2217 if (token_tags[it.tok_i] == .identifier and
2218 token_tags[it.tok_i + 1] == .colon)
2219 {
2220 name_token = it.tok_i;
2221 it.tok_i += 2;
2222 }
2223 if (token_tags[it.tok_i] == .keyword_anytype) {
2224 it.tok_i += 1;
2225 return Param{
2226 .first_doc_comment = first_doc_comment,
2227 .comptime_noalias = comptime_noalias,
2228 .name_token = name_token,
2229 .anytype_ellipsis3 = it.tok_i - 1,
2230 .type_expr = 0,
2231 };
2232 }
2233 it.tok_flag = false;
2234 }
2235 }
2236 };
2237
2238 pub fn iterate(fn_proto: FnProto, tree: Tree) Iterator {
2239 return .{
2240 .tree = &tree,
2241 .fn_proto = &fn_proto,
2242 .param_i = 0,
2243 .tok_i = fn_proto.lparen + 1,
2244 .tok_flag = true,
2245 };
2246 }
2247 };
2248
2249 pub const StructInit = struct {
2250 ast: Ast,
2251
2252 pub const Ast = struct {
2253 lbrace: TokenIndex,
2254 fields: []const Node.Index,
2255 type_expr: Node.Index,
2256 };
2257 };
2258
2259 pub const ArrayInit = struct {
2260 ast: Ast,
2261
2262 pub const Ast = struct {
2263 lbrace: TokenIndex,
2264 elements: []const Node.Index,
2265 type_expr: Node.Index,
2266 };
2267 };
2268
2269 pub const ArrayType = struct {
2270 ast: Ast,
2271
2272 pub const Ast = struct {
2273 lbracket: TokenIndex,
2274 elem_count: Node.Index,
2275 sentinel: Node.Index,
2276 elem_type: Node.Index,
2277 };
2278 };
2279
2280 pub const PtrType = struct {
2281 size: std.builtin.TypeInfo.Pointer.Size,
2282 allowzero_token: ?TokenIndex,
2283 const_token: ?TokenIndex,
2284 volatile_token: ?TokenIndex,
2285 ast: Ast,
2286
2287 pub const Ast = struct {
2288 main_token: TokenIndex,
2289 align_node: Node.Index,
2290 sentinel: Node.Index,
2291 bit_range_start: Node.Index,
2292 bit_range_end: Node.Index,
2293 child_type: Node.Index,
2294 };
2295 };
2296
2297 pub const Slice = struct {
2298 ast: Ast,
2299
2300 pub const Ast = struct {
2301 sliced: Node.Index,
2302 lbracket: TokenIndex,
2303 start: Node.Index,
2304 end: Node.Index,
2305 sentinel: Node.Index,
2306 };
2307 };
2308
2309 pub const ContainerDecl = struct {
2310 layout_token: ?TokenIndex,
2311 ast: Ast,
2312
2313 pub const Ast = struct {
2314 main_token: TokenIndex,
2315 /// Populated when main_token is Keyword_union.
2316 enum_token: ?TokenIndex,
2317 members: []const Node.Index,
2318 arg: Node.Index,
2319 };
2320 };
2321
2322 pub const SwitchCase = struct {
2323 /// Points to the first token after the `|`. Will either be an identifier or
2324 /// a `*` (with an identifier immediately after it).
2325 payload_token: ?TokenIndex,
2326 ast: Ast,
2327
2328 pub const Ast = struct {
2329 /// If empty, this is an else case
2330 values: []const Node.Index,
2331 arrow_token: TokenIndex,
2332 target_expr: Node.Index,
2333 };
2334 };
2335
2336 pub const Asm = struct {
2337 ast: Ast,
2338 volatile_token: ?TokenIndex,
2339 first_clobber: ?TokenIndex,
2340 outputs: []const Node.Index,
2341 inputs: []const Node.Index,
2342
2343 pub const Ast = struct {
2344 asm_token: TokenIndex,
2345 template: Node.Index,
2346 items: []const Node.Index,
2347 rparen: TokenIndex,
2348 };
2349 };
2350
2351 pub const Call = struct {
2352 ast: Ast,
2353 async_token: ?TokenIndex,
2354
2355 pub const Ast = struct {
2356 lparen: TokenIndex,
2357 fn_expr: Node.Index,
2358 params: []const Node.Index,
2359 };
2360 };
2361};
2362
2363pub const Error = struct {
2364 tag: Tag,
2365 token: TokenIndex,
2366 extra: union {
2367 none: void,
2368 expected_tag: Token.Tag,
2369 } = .{ .none = {} },
2370
2371 pub const Tag = enum {
2372 asterisk_after_ptr_deref,
2373 decl_between_fields,
2374 expected_block,
2375 expected_block_or_assignment,
2376 expected_block_or_expr,
2377 expected_block_or_field,
2378 expected_container_members,
2379 expected_expr,
2380 expected_expr_or_assignment,
2381 expected_fn,
2382 expected_inlinable,
2383 expected_labelable,
2384 expected_param_list,
2385 expected_prefix_expr,
2386 expected_primary_type_expr,
2387 expected_pub_item,
2388 expected_return_type,
2389 expected_semi_or_else,
2390 expected_semi_or_lbrace,
2391 expected_statement,
2392 expected_string_literal,
2393 expected_suffix_op,
2394 expected_type_expr,
2395 expected_var_decl,
2396 expected_var_decl_or_fn,
2397 expected_loop_payload,
2398 expected_container,
2399 extra_align_qualifier,
2400 extra_allowzero_qualifier,
2401 extra_const_qualifier,
2402 extra_volatile_qualifier,
2403 ptr_mod_on_array_child_type,
2404 invalid_bit_range,
2405 invalid_token,
2406 same_line_doc_comment,
2407 unattached_doc_comment,
2408 varargs_nonfinal,
2409
2410 /// `expected_tag` is populated.
2411 expected_token,
2412 };
2413};
2414
2415pub const Node = struct {
2416 tag: Tag,
2417 main_token: TokenIndex,
2418 data: Data,
2419
2420 pub const Index = u32;
2421
2422 comptime {
2423 // Goal is to keep this under one byte for efficiency.
2424 assert(@sizeOf(Tag) == 1);
2425 }
2426
2427 /// Note: The FooComma/FooSemicolon variants exist to ease the implementation of
2428 /// Tree.lastToken()
2429 pub const Tag = enum {
2430 /// sub_list[lhs...rhs]
2431 root,
2432 /// `usingnamespace lhs;`. rhs unused. main_token is `usingnamespace`.
2433 @"usingnamespace",
2434 /// lhs is test name token (must be string literal), if any.
2435 /// rhs is the body node.
2436 test_decl,
2437 /// lhs is the index into extra_data.
2438 /// rhs is the initialization expression, if any.
2439 /// main_token is `var` or `const`.
2440 global_var_decl,
2441 /// `var a: x align(y) = rhs`
2442 /// lhs is the index into extra_data.
2443 /// main_token is `var` or `const`.
2444 local_var_decl,
2445 /// `var a: lhs = rhs`. lhs and rhs may be unused.
2446 /// Can be local or global.
2447 /// main_token is `var` or `const`.
2448 simple_var_decl,
2449 /// `var a align(lhs) = rhs`. lhs and rhs may be unused.
2450 /// Can be local or global.
2451 /// main_token is `var` or `const`.
2452 aligned_var_decl,
2453 /// lhs is the identifier token payload if any,
2454 /// rhs is the deferred expression.
2455 @"errdefer",
2456 /// lhs is unused.
2457 /// rhs is the deferred expression.
2458 @"defer",
2459 /// lhs catch rhs
2460 /// lhs catch |err| rhs
2461 /// main_token is the `catch` keyword.
2462 /// payload is determined by looking at the next token after the `catch` keyword.
2463 @"catch",
2464 /// `lhs.a`. main_token is the dot. rhs is the identifier token index.
2465 field_access,
2466 /// `lhs.?`. main_token is the dot. rhs is the `?` token index.
2467 unwrap_optional,
2468 /// `lhs == rhs`. main_token is op.
2469 equal_equal,
2470 /// `lhs != rhs`. main_token is op.
2471 bang_equal,
2472 /// `lhs < rhs`. main_token is op.
2473 less_than,
2474 /// `lhs > rhs`. main_token is op.
2475 greater_than,
2476 /// `lhs <= rhs`. main_token is op.
2477 less_or_equal,
2478 /// `lhs >= rhs`. main_token is op.
2479 greater_or_equal,
2480 /// `lhs *= rhs`. main_token is op.
2481 assign_mul,
2482 /// `lhs /= rhs`. main_token is op.
2483 assign_div,
2484 /// `lhs *= rhs`. main_token is op.
2485 assign_mod,
2486 /// `lhs += rhs`. main_token is op.
2487 assign_add,
2488 /// `lhs -= rhs`. main_token is op.
2489 assign_sub,
2490 /// `lhs <<= rhs`. main_token is op.
2491 assign_bit_shift_left,
2492 /// `lhs >>= rhs`. main_token is op.
2493 assign_bit_shift_right,
2494 /// `lhs &= rhs`. main_token is op.
2495 assign_bit_and,
2496 /// `lhs ^= rhs`. main_token is op.
2497 assign_bit_xor,
2498 /// `lhs |= rhs`. main_token is op.
2499 assign_bit_or,
2500 /// `lhs *%= rhs`. main_token is op.
2501 assign_mul_wrap,
2502 /// `lhs +%= rhs`. main_token is op.
2503 assign_add_wrap,
2504 /// `lhs -%= rhs`. main_token is op.
2505 assign_sub_wrap,
2506 /// `lhs = rhs`. main_token is op.
2507 assign,
2508 /// `lhs || rhs`. main_token is the `||`.
2509 merge_error_sets,
2510 /// `lhs * rhs`. main_token is the `*`.
2511 mul,
2512 /// `lhs / rhs`. main_token is the `/`.
2513 div,
2514 /// `lhs % rhs`. main_token is the `%`.
2515 mod,
2516 /// `lhs ** rhs`. main_token is the `**`.
2517 array_mult,
2518 /// `lhs *% rhs`. main_token is the `*%`.
2519 mul_wrap,
2520 /// `lhs + rhs`. main_token is the `+`.
2521 add,
2522 /// `lhs - rhs`. main_token is the `-`.
2523 sub,
2524 /// `lhs ++ rhs`. main_token is the `++`.
2525 array_cat,
2526 /// `lhs +% rhs`. main_token is the `+%`.
2527 add_wrap,
2528 /// `lhs -% rhs`. main_token is the `-%`.
2529 sub_wrap,
2530 /// `lhs << rhs`. main_token is the `<<`.
2531 bit_shift_left,
2532 /// `lhs >> rhs`. main_token is the `>>`.
2533 bit_shift_right,
2534 /// `lhs & rhs`. main_token is the `&`.
2535 bit_and,
2536 /// `lhs ^ rhs`. main_token is the `^`.
2537 bit_xor,
2538 /// `lhs | rhs`. main_token is the `|`.
2539 bit_or,
2540 /// `lhs orelse rhs`. main_token is the `orelse`.
2541 @"orelse",
2542 /// `lhs and rhs`. main_token is the `and`.
2543 bool_and,
2544 /// `lhs or rhs`. main_token is the `or`.
2545 bool_or,
2546 /// `op lhs`. rhs unused. main_token is op.
2547 bool_not,
2548 /// `op lhs`. rhs unused. main_token is op.
2549 negation,
2550 /// `op lhs`. rhs unused. main_token is op.
2551 bit_not,
2552 /// `op lhs`. rhs unused. main_token is op.
2553 negation_wrap,
2554 /// `op lhs`. rhs unused. main_token is op.
2555 address_of,
2556 /// `op lhs`. rhs unused. main_token is op.
2557 @"try",
2558 /// `op lhs`. rhs unused. main_token is op.
2559 @"await",
2560 /// `?lhs`. rhs unused. main_token is the `?`.
2561 optional_type,
2562 /// `[lhs]rhs`.
2563 array_type,
2564 /// `[lhs:a]b`. `ArrayTypeSentinel[rhs]`.
2565 array_type_sentinel,
2566 /// `[*]align(lhs) rhs`. lhs can be omitted.
2567 /// `*align(lhs) rhs`. lhs can be omitted.
2568 /// `[]rhs`.
2569 /// main_token is the asterisk if a pointer or the lbracket if a slice
2570 /// main_token might be a ** token, which is shared with a parent/child
2571 /// pointer type and may require special handling.
2572 ptr_type_aligned,
2573 /// `[*:lhs]rhs`. lhs can be omitted.
2574 /// `*rhs`.
2575 /// `[:lhs]rhs`.
2576 /// main_token is the asterisk if a pointer or the lbracket if a slice
2577 /// main_token might be a ** token, which is shared with a parent/child
2578 /// pointer type and may require special handling.
2579 ptr_type_sentinel,
2580 /// lhs is index into ptr_type. rhs is the element type expression.
2581 /// main_token is the asterisk if a pointer or the lbracket if a slice
2582 /// main_token might be a ** token, which is shared with a parent/child
2583 /// pointer type and may require special handling.
2584 ptr_type,
2585 /// lhs is index into ptr_type_bit_range. rhs is the element type expression.
2586 /// main_token is the asterisk if a pointer or the lbracket if a slice
2587 /// main_token might be a ** token, which is shared with a parent/child
2588 /// pointer type and may require special handling.
2589 ptr_type_bit_range,
2590 /// `lhs[rhs..]`
2591 /// main_token is the lbracket.
2592 slice_open,
2593 /// `lhs[b..c]`. rhs is index into Slice
2594 /// main_token is the lbracket.
2595 slice,
2596 /// `lhs[b..c :d]`. rhs is index into SliceSentinel
2597 /// main_token is the lbracket.
2598 slice_sentinel,
2599 /// `lhs.*`. rhs is unused.
2600 deref,
2601 /// `lhs[rhs]`.
2602 array_access,
2603 /// `lhs{rhs}`. rhs can be omitted.
2604 array_init_one,
2605 /// `lhs{rhs,}`. rhs can *not* be omitted
2606 array_init_one_comma,
2607 /// `.{lhs, rhs}`. lhs and rhs can be omitted.
2608 array_init_dot_two,
2609 /// Same as `array_init_dot_two` except there is known to be a trailing comma
2610 /// before the final rbrace.
2611 array_init_dot_two_comma,
2612 /// `.{a, b}`. `sub_list[lhs..rhs]`.
2613 array_init_dot,
2614 /// Same as `array_init_dot` except there is known to be a trailing comma
2615 /// before the final rbrace.
2616 array_init_dot_comma,
2617 /// `lhs{a, b}`. `sub_range_list[rhs]`. lhs can be omitted which means `.{a, b}`.
2618 array_init,
2619 /// Same as `array_init` except there is known to be a trailing comma
2620 /// before the final rbrace.
2621 array_init_comma,
2622 /// `lhs{.a = rhs}`. rhs can be omitted making it empty.
2623 /// main_token is the lbrace.
2624 struct_init_one,
2625 /// `lhs{.a = rhs,}`. rhs can *not* be omitted.
2626 /// main_token is the lbrace.
2627 struct_init_one_comma,
2628 /// `.{.a = lhs, .b = rhs}`. lhs and rhs can be omitted.
2629 /// main_token is the lbrace.
2630 /// No trailing comma before the rbrace.
2631 struct_init_dot_two,
2632 /// Same as `struct_init_dot_two` except there is known to be a trailing comma
2633 /// before the final rbrace.
2634 struct_init_dot_two_comma,
2635 /// `.{.a = b, .c = d}`. `sub_list[lhs..rhs]`.
2636 /// main_token is the lbrace.
2637 struct_init_dot,
2638 /// Same as `struct_init_dot` except there is known to be a trailing comma
2639 /// before the final rbrace.
2640 struct_init_dot_comma,
2641 /// `lhs{.a = b, .c = d}`. `sub_range_list[rhs]`.
2642 /// lhs can be omitted which means `.{.a = b, .c = d}`.
2643 /// main_token is the lbrace.
2644 struct_init,
2645 /// Same as `struct_init` except there is known to be a trailing comma
2646 /// before the final rbrace.
2647 struct_init_comma,
2648 /// `lhs(rhs)`. rhs can be omitted.
2649 /// main_token is the lparen.
2650 call_one,
2651 /// `lhs(rhs,)`. rhs can be omitted.
2652 /// main_token is the lparen.
2653 call_one_comma,
2654 /// `async lhs(rhs)`. rhs can be omitted.
2655 async_call_one,
2656 /// `async lhs(rhs,)`.
2657 async_call_one_comma,
2658 /// `lhs(a, b, c)`. `SubRange[rhs]`.
2659 /// main_token is the `(`.
2660 call,
2661 /// `lhs(a, b, c,)`. `SubRange[rhs]`.
2662 /// main_token is the `(`.
2663 call_comma,
2664 /// `async lhs(a, b, c)`. `SubRange[rhs]`.
2665 /// main_token is the `(`.
2666 async_call,
2667 /// `async lhs(a, b, c,)`. `SubRange[rhs]`.
2668 /// main_token is the `(`.
2669 async_call_comma,
2670 /// `switch(lhs) {}`. `SubRange[rhs]`.
2671 @"switch",
2672 /// Same as switch except there is known to be a trailing comma
2673 /// before the final rbrace
2674 switch_comma,
2675 /// `lhs => rhs`. If lhs is omitted it means `else`.
2676 /// main_token is the `=>`
2677 switch_case_one,
2678 /// `a, b, c => rhs`. `SubRange[lhs]`.
2679 /// main_token is the `=>`
2680 switch_case,
2681 /// `lhs...rhs`.
2682 switch_range,
2683 /// `while (lhs) rhs`.
2684 /// `while (lhs) |x| rhs`.
2685 while_simple,
2686 /// `while (lhs) : (a) b`. `WhileCont[rhs]`.
2687 /// `while (lhs) : (a) b`. `WhileCont[rhs]`.
2688 while_cont,
2689 /// `while (lhs) : (a) b else c`. `While[rhs]`.
2690 /// `while (lhs) |x| : (a) b else c`. `While[rhs]`.
2691 /// `while (lhs) |x| : (a) b else |y| c`. `While[rhs]`.
2692 @"while",
2693 /// `for (lhs) rhs`.
2694 for_simple,
2695 /// `for (lhs) a else b`. `if_list[rhs]`.
2696 @"for",
2697 /// `if (lhs) rhs`.
2698 /// `if (lhs) |a| rhs`.
2699 if_simple,
2700 /// `if (lhs) a else b`. `If[rhs]`.
2701 /// `if (lhs) |x| a else b`. `If[rhs]`.
2702 /// `if (lhs) |x| a else |y| b`. `If[rhs]`.
2703 @"if",
2704 /// `suspend lhs`. lhs can be omitted. rhs is unused.
2705 @"suspend",
2706 /// `resume lhs`. rhs is unused.
2707 @"resume",
2708 /// `continue`. lhs is token index of label if any. rhs is unused.
2709 @"continue",
2710 /// `break :lhs rhs`
2711 /// both lhs and rhs may be omitted.
2712 @"break",
2713 /// `return lhs`. lhs can be omitted. rhs is unused.
2714 @"return",
2715 /// `fn(a: lhs) rhs`. lhs can be omitted.
2716 /// anytype and ... parameters are omitted from the AST tree.
2717 /// main_token is the `fn` keyword.
2718 /// extern function declarations use this tag.
2719 fn_proto_simple,
2720 /// `fn(a: b, c: d) rhs`. `sub_range_list[lhs]`.
2721 /// anytype and ... parameters are omitted from the AST tree.
2722 /// main_token is the `fn` keyword.
2723 /// extern function declarations use this tag.
2724 fn_proto_multi,
2725 /// `fn(a: b) rhs linksection(e) callconv(f)`. `FnProtoOne[lhs]`.
2726 /// zero or one parameters.
2727 /// anytype and ... parameters are omitted from the AST tree.
2728 /// main_token is the `fn` keyword.
2729 /// extern function declarations use this tag.
2730 fn_proto_one,
2731 /// `fn(a: b, c: d) rhs linksection(e) callconv(f)`. `FnProto[lhs]`.
2732 /// anytype and ... parameters are omitted from the AST tree.
2733 /// main_token is the `fn` keyword.
2734 /// extern function declarations use this tag.
2735 fn_proto,
2736 /// lhs is the fn_proto.
2737 /// rhs is the function body block.
2738 /// Note that extern function declarations use the fn_proto tags rather
2739 /// than this one.
2740 fn_decl,
2741 /// `anyframe->rhs`. main_token is `anyframe`. `lhs` is arrow token index.
2742 anyframe_type,
2743 /// Both lhs and rhs unused.
2744 anyframe_literal,
2745 /// Both lhs and rhs unused.
2746 char_literal,
2747 /// Both lhs and rhs unused.
2748 integer_literal,
2749 /// Both lhs and rhs unused.
2750 float_literal,
2751 /// Both lhs and rhs unused.
2752 unreachable_literal,
2753 /// Both lhs and rhs unused.
2754 /// Most identifiers will not have explicit AST nodes, however for expressions
2755 /// which could be one of many different kinds of AST nodes, there will be an
2756 /// identifier AST node for it.
2757 identifier,
2758 /// lhs is the dot token index, rhs unused, main_token is the identifier.
2759 enum_literal,
2760 /// main_token is the string literal token
2761 /// Both lhs and rhs unused.
2762 string_literal,
2763 /// main_token is the first token index (redundant with lhs)
2764 /// lhs is the first token index; rhs is the last token index.
2765 /// Could be a series of multiline_string_literal_line tokens, or a single
2766 /// string_literal token.
2767 multiline_string_literal,
2768 /// `(lhs)`. main_token is the `(`; rhs is the token index of the `)`.
2769 grouped_expression,
2770 /// `@a(lhs, rhs)`. lhs and rhs may be omitted.
2771 /// main_token is the builtin token.
2772 builtin_call_two,
2773 /// Same as builtin_call_two but there is known to be a trailing comma before the rparen.
2774 builtin_call_two_comma,
2775 /// `@a(b, c)`. `sub_list[lhs..rhs]`.
2776 /// main_token is the builtin token.
2777 builtin_call,
2778 /// Same as builtin_call but there is known to be a trailing comma before the rparen.
2779 builtin_call_comma,
2780 /// `error{a, b}`.
2781 /// rhs is the rbrace, lhs is unused.
2782 error_set_decl,
2783 /// `struct {}`, `union {}`, `opaque {}`, `enum {}`. `extra_data[lhs..rhs]`.
2784 /// main_token is `struct`, `union`, `opaque`, `enum` keyword.
2785 container_decl,
2786 /// Same as ContainerDecl but there is known to be a trailing comma
2787 /// or semicolon before the rbrace.
2788 container_decl_trailing,
2789 /// `struct {lhs, rhs}`, `union {lhs, rhs}`, `opaque {lhs, rhs}`, `enum {lhs, rhs}`.
2790 /// lhs or rhs can be omitted.
2791 /// main_token is `struct`, `union`, `opaque`, `enum` keyword.
2792 container_decl_two,
2793 /// Same as ContainerDeclTwo except there is known to be a trailing comma
2794 /// or semicolon before the rbrace.
2795 container_decl_two_trailing,
2796 /// `union(lhs)` / `enum(lhs)`. `SubRange[rhs]`.
2797 container_decl_arg,
2798 /// Same as container_decl_arg but there is known to be a trailing
2799 /// comma or semicolon before the rbrace.
2800 container_decl_arg_trailing,
2801 /// `union(enum) {}`. `sub_list[lhs..rhs]`.
2802 /// Note that tagged unions with explicitly provided enums are represented
2803 /// by `container_decl_arg`.
2804 tagged_union,
2805 /// Same as tagged_union but there is known to be a trailing comma
2806 /// or semicolon before the rbrace.
2807 tagged_union_trailing,
2808 /// `union(enum) {lhs, rhs}`. lhs or rhs may be omitted.
2809 /// Note that tagged unions with explicitly provided enums are represented
2810 /// by `container_decl_arg`.
2811 tagged_union_two,
2812 /// Same as tagged_union_two but there is known to be a trailing comma
2813 /// or semicolon before the rbrace.
2814 tagged_union_two_trailing,
2815 /// `union(enum(lhs)) {}`. `SubRange[rhs]`.
2816 tagged_union_enum_tag,
2817 /// Same as tagged_union_enum_tag but there is known to be a trailing comma
2818 /// or semicolon before the rbrace.
2819 tagged_union_enum_tag_trailing,
2820 /// `a: lhs = rhs,`. lhs and rhs can be omitted.
2821 /// main_token is the field name identifier.
2822 /// lastToken() does not include the possible trailing comma.
2823 container_field_init,
2824 /// `a: lhs align(rhs),`. rhs can be omitted.
2825 /// main_token is the field name identifier.
2826 /// lastToken() does not include the possible trailing comma.
2827 container_field_align,
2828 /// `a: lhs align(c) = d,`. `container_field_list[rhs]`.
2829 /// main_token is the field name identifier.
2830 /// lastToken() does not include the possible trailing comma.
2831 container_field,
2832 /// `anytype`. both lhs and rhs unused.
2833 /// Used by `ContainerField`.
2834 @"anytype",
2835 /// `comptime lhs`. rhs unused.
2836 @"comptime",
2837 /// `nosuspend lhs`. rhs unused.
2838 @"nosuspend",
2839 /// `{lhs rhs}`. rhs or lhs can be omitted.
2840 /// main_token points at the lbrace.
2841 block_two,
2842 /// Same as block_two but there is known to be a semicolon before the rbrace.
2843 block_two_semicolon,
2844 /// `{}`. `sub_list[lhs..rhs]`.
2845 /// main_token points at the lbrace.
2846 block,
2847 /// Same as block but there is known to be a semicolon before the rbrace.
2848 block_semicolon,
2849 /// `asm(lhs)`. rhs is the token index of the rparen.
2850 asm_simple,
2851 /// `asm(lhs, a)`. `Asm[rhs]`.
2852 @"asm",
2853 /// `[a] "b" (c)`. lhs is 0, rhs is token index of the rparen.
2854 /// `[a] "b" (-> lhs)`. rhs is token index of the rparen.
2855 /// main_token is `a`.
2856 asm_output,
2857 /// `[a] "b" (lhs)`. rhs is token index of the rparen.
2858 /// main_token is `a`.
2859 asm_input,
2860 /// `error.a`. lhs is token index of `.`. rhs is token index of `a`.
2861 error_value,
2862 /// `lhs!rhs`. main_token is the `!`.
2863 error_union,
2864
2865 pub fn isContainerField(tag: Tag) bool {
2866 return switch (tag) {
2867 .container_field_init,
2868 .container_field_align,
2869 .container_field,
2870 => true,
2871
2872 else => false,
2873 };
2874 }
2875 };
2876
2877 pub const Data = struct {
2878 lhs: Index,
2879 rhs: Index,
2880 };
2881
2882 pub const LocalVarDecl = struct {
2883 type_node: Index,
2884 align_node: Index,
2885 };
2886
2887 pub const ArrayTypeSentinel = struct {
2888 elem_type: Index,
2889 sentinel: Index,
2890 };
2891
2892 pub const PtrType = struct {
2893 sentinel: Index,
2894 align_node: Index,
2895 };
2896
2897 pub const PtrTypeBitRange = struct {
2898 sentinel: Index,
2899 align_node: Index,
2900 bit_range_start: Index,
2901 bit_range_end: Index,
2902 };
2903
2904 pub const SubRange = struct {
2905 /// Index into sub_list.
2906 start: Index,
2907 /// Index into sub_list.
2908 end: Index,
2909 };
2910
2911 pub const If = struct {
2912 then_expr: Index,
2913 else_expr: Index,
2914 };
2915
2916 pub const ContainerField = struct {
2917 value_expr: Index,
2918 align_expr: Index,
2919 };
2920
2921 pub const GlobalVarDecl = struct {
2922 type_node: Index,
2923 align_node: Index,
2924 section_node: Index,
2925 };
2926
2927 pub const Slice = struct {
2928 start: Index,
2929 end: Index,
2930 };
2931
2932 pub const SliceSentinel = struct {
2933 start: Index,
2934 /// May be 0 if the slice is "open"
2935 end: Index,
2936 sentinel: Index,
2937 };
2938
2939 pub const While = struct {
2940 cont_expr: Index,
2941 then_expr: Index,
2942 else_expr: Index,
2943 };
2944
2945 pub const WhileCont = struct {
2946 cont_expr: Index,
2947 then_expr: Index,
2948 };
2949
2950 pub const FnProtoOne = struct {
2951 /// Populated if there is exactly 1 parameter. Otherwise there are 0 parameters.
2952 param: Index,
2953 /// Populated if align(A) is present.
2954 align_expr: Index,
2955 /// Populated if linksection(A) is present.
2956 section_expr: Index,
2957 /// Populated if callconv(A) is present.
2958 callconv_expr: Index,
2959 };
2960
2961 pub const FnProto = struct {
2962 params_start: Index,
2963 params_end: Index,
2964 /// Populated if align(A) is present.
2965 align_expr: Index,
2966 /// Populated if linksection(A) is present.
2967 section_expr: Index,
2968 /// Populated if callconv(A) is present.
2969 callconv_expr: Index,
2970 };
2971
2972 pub const Asm = struct {
2973 items_start: Index,
2974 items_end: Index,
2975 /// Needed to make lastToken() work.
2976 rparen: TokenIndex,
2977 };
2978};
lib/std/zig/parse.zig+16-17
......@@ -1,19 +1,18 @@
11const std = @import("../std.zig");
22const assert = std.debug.assert;
33const Allocator = std.mem.Allocator;
4const ast = std.zig.ast;
5const Node = ast.Node;
6const Tree = ast.Tree;
7const AstError = ast.Error;
8const TokenIndex = ast.TokenIndex;
4const Ast = std.zig.Ast;
5const Node = Ast.Node;
6const AstError = Ast.Error;
7const TokenIndex = Ast.TokenIndex;
98const Token = std.zig.Token;
109
1110pub const Error = error{ParseError} || Allocator.Error;
1211
1312/// Result should be freed with tree.deinit() when there are
1413/// no more references to any of the tokens or nodes.
15pub fn parse(gpa: *Allocator, source: [:0]const u8) Allocator.Error!Tree {
16 var tokens = ast.TokenList{};
14pub fn parse(gpa: *Allocator, source: [:0]const u8) Allocator.Error!Ast {
15 var tokens = Ast.TokenList{};
1716 defer tokens.deinit(gpa);
1817
1918 // Empirically, the zig std lib has an 8:1 ratio of source bytes to token count.
......@@ -69,7 +68,7 @@ pub fn parse(gpa: *Allocator, source: [:0]const u8) Allocator.Error!Tree {
6968 };
7069
7170 // TODO experiment with compacting the MultiArrayList slices here
72 return Tree{
71 return Ast{
7372 .source = source,
7473 .tokens = tokens.toOwnedSlice(),
7574 .nodes = parser.nodes.toOwnedSlice(),
......@@ -80,15 +79,15 @@ pub fn parse(gpa: *Allocator, source: [:0]const u8) Allocator.Error!Tree {
8079
8180const null_node: Node.Index = 0;
8281
83/// Represents in-progress parsing, will be converted to an ast.Tree after completion.
82/// Represents in-progress parsing, will be converted to an Ast after completion.
8483const Parser = struct {
8584 gpa: *Allocator,
8685 source: []const u8,
8786 token_tags: []const Token.Tag,
88 token_starts: []const ast.ByteOffset,
87 token_starts: []const Ast.ByteOffset,
8988 tok_i: TokenIndex,
9089 errors: std.ArrayListUnmanaged(AstError),
91 nodes: ast.NodeList,
90 nodes: Ast.NodeList,
9291 extra_data: std.ArrayListUnmanaged(Node.Index),
9392 scratch: std.ArrayListUnmanaged(Node.Index),
9493
......@@ -121,13 +120,13 @@ const Parser = struct {
121120 };
122121 }
123122
124 fn addNode(p: *Parser, elem: ast.NodeList.Elem) Allocator.Error!Node.Index {
123 fn addNode(p: *Parser, elem: Ast.NodeList.Elem) Allocator.Error!Node.Index {
125124 const result = @intCast(Node.Index, p.nodes.len);
126125 try p.nodes.append(p.gpa, elem);
127126 return result;
128127 }
129128
130 fn setNode(p: *Parser, i: usize, elem: ast.NodeList.Elem) Node.Index {
129 fn setNode(p: *Parser, i: usize, elem: Ast.NodeList.Elem) Node.Index {
131130 p.nodes.set(i, elem);
132131 return @intCast(Node.Index, i);
133132 }
......@@ -148,7 +147,7 @@ const Parser = struct {
148147 return result;
149148 }
150149
151 fn warn(p: *Parser, tag: ast.Error.Tag) error{OutOfMemory}!void {
150 fn warn(p: *Parser, tag: Ast.Error.Tag) error{OutOfMemory}!void {
152151 @setCold(true);
153152 try p.warnMsg(.{ .tag = tag, .token = p.tok_i });
154153 }
......@@ -161,12 +160,12 @@ const Parser = struct {
161160 .extra = .{ .expected_tag = expected_token },
162161 });
163162 }
164 fn warnMsg(p: *Parser, msg: ast.Error) error{OutOfMemory}!void {
163 fn warnMsg(p: *Parser, msg: Ast.Error) error{OutOfMemory}!void {
165164 @setCold(true);
166165 try p.errors.append(p.gpa, msg);
167166 }
168167
169 fn fail(p: *Parser, tag: ast.Error.Tag) error{ ParseError, OutOfMemory } {
168 fn fail(p: *Parser, tag: Ast.Error.Tag) error{ ParseError, OutOfMemory } {
170169 @setCold(true);
171170 return p.failMsg(.{ .tag = tag, .token = p.tok_i });
172171 }
......@@ -180,7 +179,7 @@ const Parser = struct {
180179 });
181180 }
182181
183 fn failMsg(p: *Parser, msg: ast.Error) error{ ParseError, OutOfMemory } {
182 fn failMsg(p: *Parser, msg: Ast.Error) error{ ParseError, OutOfMemory } {
184183 @setCold(true);
185184 try p.warnMsg(msg);
186185 return error.ParseError;
lib/std/zig/parser_test.zig+1-1
......@@ -5308,7 +5308,7 @@ fn testCanonical(source: [:0]const u8) !void {
53085308 return testTransform(source, source);
53095309}
53105310
5311const Error = std.zig.ast.Error.Tag;
5311const Error = std.zig.Ast.Error.Tag;
53125312
53135313fn testError(source: [:0]const u8, expected_errors: []const Error) !void {
53145314 var tree = try std.zig.parse(std.testing.allocator, source);
lib/std/zig/render.zig+76-76
......@@ -3,17 +3,17 @@ const assert = std.debug.assert;
33const mem = std.mem;
44const Allocator = std.mem.Allocator;
55const meta = std.meta;
6const ast = std.zig.ast;
6const Ast = std.zig.Ast;
77const Token = std.zig.Token;
88
99const indent_delta = 4;
1010const asm_indent_delta = 2;
1111
12pub const Error = ast.Tree.RenderError;
12pub const Error = Ast.RenderError;
1313
1414const Ais = AutoIndentingStream(std.ArrayList(u8).Writer);
1515
16pub fn renderTree(buffer: *std.ArrayList(u8), tree: ast.Tree) Error!void {
16pub fn renderTree(buffer: *std.ArrayList(u8), tree: Ast) Error!void {
1717 assert(tree.errors.len == 0); // Cannot render an invalid tree.
1818 var auto_indenting_stream = Ais{
1919 .indent_delta = indent_delta,
......@@ -37,7 +37,7 @@ pub fn renderTree(buffer: *std.ArrayList(u8), tree: ast.Tree) Error!void {
3737}
3838
3939/// Render all members in the given slice, keeping empty lines where appropriate
40fn renderMembers(gpa: *Allocator, ais: *Ais, tree: ast.Tree, members: []const ast.Node.Index) Error!void {
40fn renderMembers(gpa: *Allocator, ais: *Ais, tree: Ast, members: []const Ast.Node.Index) Error!void {
4141 if (members.len == 0) return;
4242 try renderMember(gpa, ais, tree, members[0], .newline);
4343 for (members[1..]) |member| {
......@@ -46,7 +46,7 @@ fn renderMembers(gpa: *Allocator, ais: *Ais, tree: ast.Tree, members: []const as
4646 }
4747}
4848
49fn renderMember(gpa: *Allocator, ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: Space) Error!void {
49fn renderMember(gpa: *Allocator, ais: *Ais, tree: Ast, decl: Ast.Node.Index, space: Space) Error!void {
5050 const token_tags = tree.tokens.items(.tag);
5151 const main_tokens = tree.nodes.items(.main_token);
5252 const datas = tree.nodes.items(.data);
......@@ -83,9 +83,9 @@ fn renderMember(gpa: *Allocator, ais: *Ais, tree: ast.Tree, decl: ast.Node.Index
8383 switch (tree.nodes.items(.tag)[fn_proto]) {
8484 .fn_proto_one, .fn_proto => {
8585 const callconv_expr = if (tree.nodes.items(.tag)[fn_proto] == .fn_proto_one)
86 tree.extraData(datas[fn_proto].lhs, ast.Node.FnProtoOne).callconv_expr
86 tree.extraData(datas[fn_proto].lhs, Ast.Node.FnProtoOne).callconv_expr
8787 else
88 tree.extraData(datas[fn_proto].lhs, ast.Node.FnProto).callconv_expr;
88 tree.extraData(datas[fn_proto].lhs, Ast.Node.FnProto).callconv_expr;
8989 if (callconv_expr != 0 and tree.nodes.items(.tag)[callconv_expr] == .enum_literal) {
9090 if (mem.eql(u8, "Inline", tree.tokenSlice(main_tokens[callconv_expr]))) {
9191 try ais.writer().writeAll("inline ");
......@@ -168,7 +168,7 @@ fn renderMember(gpa: *Allocator, ais: *Ais, tree: ast.Tree, decl: ast.Node.Index
168168}
169169
170170/// Render all expressions in the slice, keeping empty lines where appropriate
171fn renderExpressions(gpa: *Allocator, ais: *Ais, tree: ast.Tree, expressions: []const ast.Node.Index, space: Space) Error!void {
171fn renderExpressions(gpa: *Allocator, ais: *Ais, tree: Ast, expressions: []const Ast.Node.Index, space: Space) Error!void {
172172 if (expressions.len == 0) return;
173173 try renderExpression(gpa, ais, tree, expressions[0], space);
174174 for (expressions[1..]) |expression| {
......@@ -177,7 +177,7 @@ fn renderExpressions(gpa: *Allocator, ais: *Ais, tree: ast.Tree, expressions: []
177177 }
178178}
179179
180fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void {
180fn renderExpression(gpa: *Allocator, ais: *Ais, tree: Ast, node: Ast.Node.Index, space: Space) Error!void {
181181 const token_tags = tree.tokens.items(.tag);
182182 const main_tokens = tree.nodes.items(.main_token);
183183 const node_tags = tree.nodes.items(.tag);
......@@ -220,7 +220,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
220220 .block_two,
221221 .block_two_semicolon,
222222 => {
223 const statements = [2]ast.Node.Index{ datas[node].lhs, datas[node].rhs };
223 const statements = [2]Ast.Node.Index{ datas[node].lhs, datas[node].rhs };
224224 if (datas[node].lhs == 0) {
225225 return renderBlock(gpa, ais, tree, node, statements[0..0], space);
226226 } else if (datas[node].rhs == 0) {
......@@ -413,11 +413,11 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
413413 .ptr_type_bit_range => return renderPtrType(gpa, ais, tree, tree.ptrTypeBitRange(node), space),
414414
415415 .array_init_one, .array_init_one_comma => {
416 var elements: [1]ast.Node.Index = undefined;
416 var elements: [1]Ast.Node.Index = undefined;
417417 return renderArrayInit(gpa, ais, tree, tree.arrayInitOne(&elements, node), space);
418418 },
419419 .array_init_dot_two, .array_init_dot_two_comma => {
420 var elements: [2]ast.Node.Index = undefined;
420 var elements: [2]Ast.Node.Index = undefined;
421421 return renderArrayInit(gpa, ais, tree, tree.arrayInitDotTwo(&elements, node), space);
422422 },
423423 .array_init_dot,
......@@ -428,11 +428,11 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
428428 => return renderArrayInit(gpa, ais, tree, tree.arrayInit(node), space),
429429
430430 .struct_init_one, .struct_init_one_comma => {
431 var fields: [1]ast.Node.Index = undefined;
431 var fields: [1]Ast.Node.Index = undefined;
432432 return renderStructInit(gpa, ais, tree, node, tree.structInitOne(&fields, node), space);
433433 },
434434 .struct_init_dot_two, .struct_init_dot_two_comma => {
435 var fields: [2]ast.Node.Index = undefined;
435 var fields: [2]Ast.Node.Index = undefined;
436436 return renderStructInit(gpa, ais, tree, node, tree.structInitDotTwo(&fields, node), space);
437437 },
438438 .struct_init_dot,
......@@ -443,7 +443,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
443443 => return renderStructInit(gpa, ais, tree, node, tree.structInit(node), space),
444444
445445 .call_one, .call_one_comma, .async_call_one, .async_call_one_comma => {
446 var params: [1]ast.Node.Index = undefined;
446 var params: [1]Ast.Node.Index = undefined;
447447 return renderCall(gpa, ais, tree, tree.callOne(&params, node), space);
448448 },
449449
......@@ -536,7 +536,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
536536 => return renderContainerDecl(gpa, ais, tree, node, tree.containerDecl(node), space),
537537
538538 .container_decl_two, .container_decl_two_trailing => {
539 var buffer: [2]ast.Node.Index = undefined;
539 var buffer: [2]Ast.Node.Index = undefined;
540540 return renderContainerDecl(gpa, ais, tree, node, tree.containerDeclTwo(&buffer, node), space);
541541 },
542542 .container_decl_arg,
......@@ -548,7 +548,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
548548 => return renderContainerDecl(gpa, ais, tree, node, tree.taggedUnion(node), space),
549549
550550 .tagged_union_two, .tagged_union_two_trailing => {
551 var buffer: [2]ast.Node.Index = undefined;
551 var buffer: [2]Ast.Node.Index = undefined;
552552 return renderContainerDecl(gpa, ais, tree, node, tree.taggedUnionTwo(&buffer, node), space);
553553 },
554554 .tagged_union_enum_tag,
......@@ -619,12 +619,12 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
619619 },
620620
621621 .fn_proto_simple => {
622 var params: [1]ast.Node.Index = undefined;
622 var params: [1]Ast.Node.Index = undefined;
623623 return renderFnProto(gpa, ais, tree, tree.fnProtoSimple(&params, node), space);
624624 },
625625 .fn_proto_multi => return renderFnProto(gpa, ais, tree, tree.fnProtoMulti(node), space),
626626 .fn_proto_one => {
627 var params: [1]ast.Node.Index = undefined;
627 var params: [1]Ast.Node.Index = undefined;
628628 return renderFnProto(gpa, ais, tree, tree.fnProtoOne(&params, node), space);
629629 },
630630 .fn_proto => return renderFnProto(gpa, ais, tree, tree.fnProto(node), space),
......@@ -645,7 +645,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
645645 => {
646646 const switch_token = main_tokens[node];
647647 const condition = datas[node].lhs;
648 const extra = tree.extraData(datas[node].rhs, ast.Node.SubRange);
648 const extra = tree.extraData(datas[node].rhs, Ast.Node.SubRange);
649649 const cases = tree.extra_data[extra.start..extra.end];
650650 const rparen = tree.lastToken(condition) + 1;
651651
......@@ -704,8 +704,8 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
704704fn renderArrayType(
705705 gpa: *Allocator,
706706 ais: *Ais,
707 tree: ast.Tree,
708 array_type: ast.full.ArrayType,
707 tree: Ast,
708 array_type: Ast.full.ArrayType,
709709 space: Space,
710710) Error!void {
711711 const rbracket = tree.firstToken(array_type.ast.elem_type) - 1;
......@@ -726,8 +726,8 @@ fn renderArrayType(
726726fn renderPtrType(
727727 gpa: *Allocator,
728728 ais: *Ais,
729 tree: ast.Tree,
730 ptr_type: ast.full.PtrType,
729 tree: Ast,
730 ptr_type: Ast.full.PtrType,
731731 space: Space,
732732) Error!void {
733733 switch (ptr_type.size) {
......@@ -811,9 +811,9 @@ fn renderPtrType(
811811fn renderSlice(
812812 gpa: *Allocator,
813813 ais: *Ais,
814 tree: ast.Tree,
815 slice_node: ast.Node.Index,
816 slice: ast.full.Slice,
814 tree: Ast,
815 slice_node: Ast.Node.Index,
816 slice: Ast.full.Slice,
817817 space: Space,
818818) Error!void {
819819 const node_tags = tree.nodes.items(.tag);
......@@ -847,8 +847,8 @@ fn renderSlice(
847847fn renderAsmOutput(
848848 gpa: *Allocator,
849849 ais: *Ais,
850 tree: ast.Tree,
851 asm_output: ast.Node.Index,
850 tree: Ast,
851 asm_output: Ast.Node.Index,
852852 space: Space,
853853) Error!void {
854854 const token_tags = tree.tokens.items(.tag);
......@@ -877,8 +877,8 @@ fn renderAsmOutput(
877877fn renderAsmInput(
878878 gpa: *Allocator,
879879 ais: *Ais,
880 tree: ast.Tree,
881 asm_input: ast.Node.Index,
880 tree: Ast,
881 asm_input: Ast.Node.Index,
882882 space: Space,
883883) Error!void {
884884 const node_tags = tree.nodes.items(.tag);
......@@ -896,7 +896,7 @@ fn renderAsmInput(
896896 return renderToken(ais, tree, datas[asm_input].rhs, space); // rparen
897897}
898898
899fn renderVarDecl(gpa: *Allocator, ais: *Ais, tree: ast.Tree, var_decl: ast.full.VarDecl) Error!void {
899fn renderVarDecl(gpa: *Allocator, ais: *Ais, tree: Ast, var_decl: Ast.full.VarDecl) Error!void {
900900 if (var_decl.visib_token) |visib_token| {
901901 try renderToken(ais, tree, visib_token, Space.space); // pub
902902 }
......@@ -985,7 +985,7 @@ fn renderVarDecl(gpa: *Allocator, ais: *Ais, tree: ast.Tree, var_decl: ast.full.
985985 return renderToken(ais, tree, var_decl.ast.mut_token + 2, .newline); // ;
986986}
987987
988fn renderIf(gpa: *Allocator, ais: *Ais, tree: ast.Tree, if_node: ast.full.If, space: Space) Error!void {
988fn renderIf(gpa: *Allocator, ais: *Ais, tree: Ast, if_node: Ast.full.If, space: Space) Error!void {
989989 return renderWhile(gpa, ais, tree, .{
990990 .ast = .{
991991 .while_token = if_node.ast.if_token,
......@@ -1004,7 +1004,7 @@ fn renderIf(gpa: *Allocator, ais: *Ais, tree: ast.Tree, if_node: ast.full.If, sp
10041004
10051005/// Note that this function is additionally used to render if and for expressions, with
10061006/// respective values set to null.
1007fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Space) Error!void {
1007fn renderWhile(gpa: *Allocator, ais: *Ais, tree: Ast, while_node: Ast.full.While, space: Space) Error!void {
10081008 const node_tags = tree.nodes.items(.tag);
10091009 const token_tags = tree.tokens.items(.tag);
10101010
......@@ -1109,8 +1109,8 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full.
11091109fn renderContainerField(
11101110 gpa: *Allocator,
11111111 ais: *Ais,
1112 tree: ast.Tree,
1113 field: ast.full.ContainerField,
1112 tree: Ast,
1113 field: Ast.full.ContainerField,
11141114 space: Space,
11151115) Error!void {
11161116 if (field.comptime_token) |t| {
......@@ -1183,9 +1183,9 @@ fn renderContainerField(
11831183fn renderBuiltinCall(
11841184 gpa: *Allocator,
11851185 ais: *Ais,
1186 tree: ast.Tree,
1187 builtin_token: ast.TokenIndex,
1188 params: []const ast.Node.Index,
1186 tree: Ast,
1187 builtin_token: Ast.TokenIndex,
1188 params: []const Ast.Node.Index,
11891189 space: Space,
11901190) Error!void {
11911191 const token_tags = tree.tokens.items(.tag);
......@@ -1238,7 +1238,7 @@ fn renderBuiltinCall(
12381238 }
12391239}
12401240
1241fn renderFnProto(gpa: *Allocator, ais: *Ais, tree: ast.Tree, fn_proto: ast.full.FnProto, space: Space) Error!void {
1241fn renderFnProto(gpa: *Allocator, ais: *Ais, tree: Ast, fn_proto: Ast.full.FnProto, space: Space) Error!void {
12421242 const token_tags = tree.tokens.items(.tag);
12431243 const token_starts = tree.tokens.items(.start);
12441244
......@@ -1438,8 +1438,8 @@ fn renderFnProto(gpa: *Allocator, ais: *Ais, tree: ast.Tree, fn_proto: ast.full.
14381438fn renderSwitchCase(
14391439 gpa: *Allocator,
14401440 ais: *Ais,
1441 tree: ast.Tree,
1442 switch_case: ast.full.SwitchCase,
1441 tree: Ast,
1442 switch_case: Ast.full.SwitchCase,
14431443 space: Space,
14441444) Error!void {
14451445 const node_tags = tree.nodes.items(.tag);
......@@ -1491,9 +1491,9 @@ fn renderSwitchCase(
14911491fn renderBlock(
14921492 gpa: *Allocator,
14931493 ais: *Ais,
1494 tree: ast.Tree,
1495 block_node: ast.Node.Index,
1496 statements: []const ast.Node.Index,
1494 tree: Ast,
1495 block_node: Ast.Node.Index,
1496 statements: []const Ast.Node.Index,
14971497 space: Space,
14981498) Error!void {
14991499 const token_tags = tree.tokens.items(.tag);
......@@ -1531,9 +1531,9 @@ fn renderBlock(
15311531fn renderStructInit(
15321532 gpa: *Allocator,
15331533 ais: *Ais,
1534 tree: ast.Tree,
1535 struct_node: ast.Node.Index,
1536 struct_init: ast.full.StructInit,
1534 tree: Ast,
1535 struct_node: Ast.Node.Index,
1536 struct_init: Ast.full.StructInit,
15371537 space: Space,
15381538) Error!void {
15391539 const token_tags = tree.tokens.items(.tag);
......@@ -1590,8 +1590,8 @@ fn renderStructInit(
15901590fn renderArrayInit(
15911591 gpa: *Allocator,
15921592 ais: *Ais,
1593 tree: ast.Tree,
1594 array_init: ast.full.ArrayInit,
1593 tree: Ast,
1594 array_init: Ast.full.ArrayInit,
15951595 space: Space,
15961596) Error!void {
15971597 const token_tags = tree.tokens.items(.tag);
......@@ -1787,9 +1787,9 @@ fn renderArrayInit(
17871787fn renderContainerDecl(
17881788 gpa: *Allocator,
17891789 ais: *Ais,
1790 tree: ast.Tree,
1791 container_decl_node: ast.Node.Index,
1792 container_decl: ast.full.ContainerDecl,
1790 tree: Ast,
1791 container_decl_node: Ast.Node.Index,
1792 container_decl: Ast.full.ContainerDecl,
17931793 space: Space,
17941794) Error!void {
17951795 const token_tags = tree.tokens.items(.tag);
......@@ -1799,7 +1799,7 @@ fn renderContainerDecl(
17991799 try renderToken(ais, tree, layout_token, .space);
18001800 }
18011801
1802 var lbrace: ast.TokenIndex = undefined;
1802 var lbrace: Ast.TokenIndex = undefined;
18031803 if (container_decl.ast.enum_token) |enum_token| {
18041804 try renderToken(ais, tree, container_decl.ast.main_token, .none); // union
18051805 try renderToken(ais, tree, enum_token - 1, .none); // lparen
......@@ -1869,8 +1869,8 @@ fn renderContainerDecl(
18691869fn renderAsm(
18701870 gpa: *Allocator,
18711871 ais: *Ais,
1872 tree: ast.Tree,
1873 asm_node: ast.full.Asm,
1872 tree: Ast,
1873 asm_node: Ast.full.Asm,
18741874 space: Space,
18751875) Error!void {
18761876 const token_tags = tree.tokens.items(.tag);
......@@ -2018,8 +2018,8 @@ fn renderAsm(
20182018fn renderCall(
20192019 gpa: *Allocator,
20202020 ais: *Ais,
2021 tree: ast.Tree,
2022 call: ast.full.Call,
2021 tree: Ast,
2022 call: Ast.full.Call,
20232023 space: Space,
20242024) Error!void {
20252025 const token_tags = tree.tokens.items(.tag);
......@@ -2091,7 +2091,7 @@ fn renderCall(
20912091
20922092/// Renders the given expression indented, popping the indent before rendering
20932093/// any following line comments
2094fn renderExpressionIndented(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void {
2094fn renderExpressionIndented(gpa: *Allocator, ais: *Ais, tree: Ast, node: Ast.Node.Index, space: Space) Error!void {
20952095 const token_starts = tree.tokens.items(.start);
20962096 const token_tags = tree.tokens.items(.tag);
20972097
......@@ -2148,7 +2148,7 @@ fn renderExpressionIndented(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: as
21482148}
21492149
21502150/// Render an expression, and the comma that follows it, if it is present in the source.
2151fn renderExpressionComma(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void {
2151fn renderExpressionComma(gpa: *Allocator, ais: *Ais, tree: Ast, node: Ast.Node.Index, space: Space) Error!void {
21522152 const token_tags = tree.tokens.items(.tag);
21532153 const maybe_comma = tree.lastToken(node) + 1;
21542154 if (token_tags[maybe_comma] == .comma) {
......@@ -2159,7 +2159,7 @@ fn renderExpressionComma(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.N
21592159 }
21602160}
21612161
2162fn renderTokenComma(ais: *Ais, tree: ast.Tree, token: ast.TokenIndex, space: Space) Error!void {
2162fn renderTokenComma(ais: *Ais, tree: Ast, token: Ast.TokenIndex, space: Space) Error!void {
21632163 const token_tags = tree.tokens.items(.tag);
21642164 const maybe_comma = token + 1;
21652165 if (token_tags[maybe_comma] == .comma) {
......@@ -2191,7 +2191,7 @@ const Space = enum {
21912191 skip,
21922192};
21932193
2194fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Space) Error!void {
2194fn renderToken(ais: *Ais, tree: Ast, token_index: Ast.TokenIndex, space: Space) Error!void {
21952195 const token_tags = tree.tokens.items(.tag);
21962196 const token_starts = tree.tokens.items(.start);
21972197
......@@ -2238,7 +2238,7 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp
22382238/// `start_token` to `end_token`. This is used to determine if e.g. a
22392239/// fn_proto should be wrapped and have a trailing comma inserted even if
22402240/// there is none in the source.
2241fn hasComment(tree: ast.Tree, start_token: ast.TokenIndex, end_token: ast.TokenIndex) bool {
2241fn hasComment(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool {
22422242 const token_starts = tree.tokens.items(.start);
22432243
22442244 var i = start_token;
......@@ -2253,7 +2253,7 @@ fn hasComment(tree: ast.Tree, start_token: ast.TokenIndex, end_token: ast.TokenI
22532253
22542254/// Returns true if there exists a multiline string literal between the start
22552255/// of token `start_token` and the start of token `end_token`.
2256fn hasMultilineString(tree: ast.Tree, start_token: ast.TokenIndex, end_token: ast.TokenIndex) bool {
2256fn hasMultilineString(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool {
22572257 const token_tags = tree.tokens.items(.tag);
22582258
22592259 for (token_tags[start_token..end_token]) |tag| {
......@@ -2268,7 +2268,7 @@ fn hasMultilineString(tree: ast.Tree, start_token: ast.TokenIndex, end_token: as
22682268
22692269/// Assumes that start is the first byte past the previous token and
22702270/// that end is the last byte before the next token.
2271fn renderComments(ais: *Ais, tree: ast.Tree, start: usize, end: usize) Error!bool {
2271fn renderComments(ais: *Ais, tree: Ast, start: usize, end: usize) Error!bool {
22722272 var index: usize = start;
22732273 while (mem.indexOf(u8, tree.source[index..end], "//")) |offset| {
22742274 const comment_start = index + offset;
......@@ -2325,12 +2325,12 @@ fn renderComments(ais: *Ais, tree: ast.Tree, start: usize, end: usize) Error!boo
23252325 return index != start;
23262326}
23272327
2328fn renderExtraNewline(ais: *Ais, tree: ast.Tree, node: ast.Node.Index) Error!void {
2328fn renderExtraNewline(ais: *Ais, tree: Ast, node: Ast.Node.Index) Error!void {
23292329 return renderExtraNewlineToken(ais, tree, tree.firstToken(node));
23302330}
23312331
23322332/// Check if there is an empty line immediately before the given token. If so, render it.
2333fn renderExtraNewlineToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex) Error!void {
2333fn renderExtraNewlineToken(ais: *Ais, tree: Ast, token_index: Ast.TokenIndex) Error!void {
23342334 const token_starts = tree.tokens.items(.start);
23352335 const token_start = token_starts[token_index];
23362336 if (token_start == 0) return;
......@@ -2355,7 +2355,7 @@ fn renderExtraNewlineToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenInde
23552355
23562356/// end_token is the token one past the last doc comment token. This function
23572357/// searches backwards from there.
2358fn renderDocComments(ais: *Ais, tree: ast.Tree, end_token: ast.TokenIndex) Error!void {
2358fn renderDocComments(ais: *Ais, tree: Ast, end_token: Ast.TokenIndex) Error!void {
23592359 // Search backwards for the first doc comment.
23602360 const token_tags = tree.tokens.items(.tag);
23612361 if (end_token == 0) return;
......@@ -2376,7 +2376,7 @@ fn renderDocComments(ais: *Ais, tree: ast.Tree, end_token: ast.TokenIndex) Error
23762376}
23772377
23782378/// start_token is first container doc comment token.
2379fn renderContainerDocComments(ais: *Ais, tree: ast.Tree, start_token: ast.TokenIndex) Error!void {
2379fn renderContainerDocComments(ais: *Ais, tree: Ast, start_token: Ast.TokenIndex) Error!void {
23802380 const token_tags = tree.tokens.items(.tag);
23812381 var tok = start_token;
23822382 while (token_tags[tok] == .container_doc_comment) : (tok += 1) {
......@@ -2390,7 +2390,7 @@ fn renderContainerDocComments(ais: *Ais, tree: ast.Tree, start_token: ast.TokenI
23902390 }
23912391}
23922392
2393fn tokenSliceForRender(tree: ast.Tree, token_index: ast.TokenIndex) []const u8 {
2393fn tokenSliceForRender(tree: Ast, token_index: Ast.TokenIndex) []const u8 {
23942394 var ret = tree.tokenSlice(token_index);
23952395 if (tree.tokens.items(.tag)[token_index] == .multiline_string_literal_line) {
23962396 assert(ret[ret.len - 1] == '\n');
......@@ -2399,7 +2399,7 @@ fn tokenSliceForRender(tree: ast.Tree, token_index: ast.TokenIndex) []const u8 {
23992399 return ret;
24002400}
24012401
2402fn hasSameLineComment(tree: ast.Tree, token_index: ast.TokenIndex) bool {
2402fn hasSameLineComment(tree: Ast, token_index: Ast.TokenIndex) bool {
24032403 const token_starts = tree.tokens.items(.start);
24042404 const between_source = tree.source[token_starts[token_index]..token_starts[token_index + 1]];
24052405 for (between_source) |byte| switch (byte) {
......@@ -2412,7 +2412,7 @@ fn hasSameLineComment(tree: ast.Tree, token_index: ast.TokenIndex) bool {
24122412
24132413/// Returns `true` if and only if there are any tokens or line comments between
24142414/// start_token and end_token.
2415fn anythingBetween(tree: ast.Tree, start_token: ast.TokenIndex, end_token: ast.TokenIndex) bool {
2415fn anythingBetween(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool {
24162416 if (start_token + 1 != end_token) return true;
24172417 const token_starts = tree.tokens.items(.start);
24182418 const between_source = tree.source[token_starts[start_token]..token_starts[start_token + 1]];
......@@ -2431,7 +2431,7 @@ fn writeFixingWhitespace(writer: std.ArrayList(u8).Writer, slice: []const u8) Er
24312431 };
24322432}
24332433
2434fn nodeIsBlock(tag: ast.Node.Tag) bool {
2434fn nodeIsBlock(tag: Ast.Node.Tag) bool {
24352435 return switch (tag) {
24362436 .block,
24372437 .block_semicolon,
......@@ -2450,7 +2450,7 @@ fn nodeIsBlock(tag: ast.Node.Tag) bool {
24502450 };
24512451}
24522452
2453fn nodeIsIfForWhileSwitch(tag: ast.Node.Tag) bool {
2453fn nodeIsIfForWhileSwitch(tag: Ast.Node.Tag) bool {
24542454 return switch (tag) {
24552455 .@"if",
24562456 .if_simple,
......@@ -2466,7 +2466,7 @@ fn nodeIsIfForWhileSwitch(tag: ast.Node.Tag) bool {
24662466 };
24672467}
24682468
2469fn nodeCausesSliceOpSpace(tag: ast.Node.Tag) bool {
2469fn nodeCausesSliceOpSpace(tag: Ast.Node.Tag) bool {
24702470 return switch (tag) {
24712471 .@"catch",
24722472 .add,
......@@ -2516,7 +2516,7 @@ fn nodeCausesSliceOpSpace(tag: ast.Node.Tag) bool {
25162516}
25172517
25182518// Returns the number of nodes in `expr` that are on the same line as `rtoken`.
2519fn rowSize(tree: ast.Tree, exprs: []const ast.Node.Index, rtoken: ast.TokenIndex) usize {
2519fn rowSize(tree: Ast, exprs: []const Ast.Node.Index, rtoken: Ast.TokenIndex) usize {
25202520 const token_tags = tree.tokens.items(.tag);
25212521
25222522 const first_token = tree.firstToken(exprs[0]);
src/AstGen.zig+252-252
......@@ -2,7 +2,7 @@
22const AstGen = @This();
33
44const std = @import("std");
5const ast = std.zig.ast;
5const Ast = std.zig.Ast;
66const mem = std.mem;
77const Allocator = std.mem.Allocator;
88const assert = std.debug.assert;
......@@ -13,7 +13,7 @@ const trace = @import("tracy.zig").trace;
1313const BuiltinFn = @import("BuiltinFn.zig");
1414
1515gpa: *Allocator,
16tree: *const ast.Tree,
16tree: *const Ast,
1717instructions: std.MultiArrayList(Zir.Inst) = .{},
1818extra: ArrayListUnmanaged(u32) = .{},
1919string_bytes: ArrayListUnmanaged(u8) = .{},
......@@ -36,7 +36,7 @@ compile_errors: ArrayListUnmanaged(Zir.Inst.CompileErrors.Item) = .{},
3636fn_block: ?*GenZir = null,
3737/// Maps string table indexes to the first `@import` ZIR instruction
3838/// that uses this string as the operand.
39imports: std.AutoArrayHashMapUnmanaged(u32, ast.TokenIndex) = .{},
39imports: std.AutoArrayHashMapUnmanaged(u32, Ast.TokenIndex) = .{},
4040
4141const InnerError = error{ OutOfMemory, AnalysisFail };
4242
......@@ -70,7 +70,7 @@ fn appendRefsAssumeCapacity(astgen: *AstGen, refs: []const Zir.Inst.Ref) void {
7070 astgen.extra.appendSliceAssumeCapacity(coerced);
7171}
7272
73pub fn generate(gpa: *Allocator, tree: ast.Tree) Allocator.Error!Zir {
73pub fn generate(gpa: *Allocator, tree: Ast) Allocator.Error!Zir {
7474 var arena = std.heap.ArenaAllocator.init(gpa);
7575 defer arena.deinit();
7676
......@@ -106,7 +106,7 @@ pub fn generate(gpa: *Allocator, tree: ast.Tree) Allocator.Error!Zir {
106106 };
107107 defer gen_scope.instructions.deinit(gpa);
108108
109 const container_decl: ast.full.ContainerDecl = .{
109 const container_decl: Ast.full.ContainerDecl = .{
110110 .layout_token = null,
111111 .ast = .{
112112 .main_token = undefined,
......@@ -265,7 +265,7 @@ pub const bool_rl: ResultLoc = .{ .ty = .bool_type };
265265pub const type_rl: ResultLoc = .{ .ty = .type_type };
266266pub const coerced_type_rl: ResultLoc = .{ .coerced_ty = .type_type };
267267
268fn typeExpr(gz: *GenZir, scope: *Scope, type_node: ast.Node.Index) InnerError!Zir.Inst.Ref {
268fn typeExpr(gz: *GenZir, scope: *Scope, type_node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
269269 const prev_force_comptime = gz.force_comptime;
270270 gz.force_comptime = true;
271271 defer gz.force_comptime = prev_force_comptime;
......@@ -278,8 +278,8 @@ fn reachableExpr(
278278 gz: *GenZir,
279279 scope: *Scope,
280280 rl: ResultLoc,
281 node: ast.Node.Index,
282 src_node: ast.Node.Index,
281 node: Ast.Node.Index,
282 src_node: Ast.Node.Index,
283283) InnerError!Zir.Inst.Ref {
284284 const result_inst = try expr(gz, scope, rl, node);
285285 if (gz.refIsNoReturn(result_inst)) {
......@@ -290,7 +290,7 @@ fn reachableExpr(
290290 return result_inst;
291291}
292292
293fn lvalExpr(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref {
293fn lvalExpr(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
294294 const astgen = gz.astgen;
295295 const tree = astgen.tree;
296296 const node_tags = tree.nodes.items(.tag);
......@@ -481,7 +481,7 @@ fn lvalExpr(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Ins
481481/// When `rl` is discard, ptr, inferred_ptr, or inferred_ptr, the
482482/// result instruction can be used to inspect whether it is isNoReturn() but that is it,
483483/// it must otherwise not be used.
484fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref {
484fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
485485 const astgen = gz.astgen;
486486 const tree = astgen.tree;
487487 const main_tokens = tree.nodes.items(.main_token);
......@@ -640,13 +640,13 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
640640
641641 .builtin_call_two, .builtin_call_two_comma => {
642642 if (node_datas[node].lhs == 0) {
643 const params = [_]ast.Node.Index{};
643 const params = [_]Ast.Node.Index{};
644644 return builtinCall(gz, scope, rl, node, &params);
645645 } else if (node_datas[node].rhs == 0) {
646 const params = [_]ast.Node.Index{node_datas[node].lhs};
646 const params = [_]Ast.Node.Index{node_datas[node].lhs};
647647 return builtinCall(gz, scope, rl, node, &params);
648648 } else {
649 const params = [_]ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs };
649 const params = [_]Ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs };
650650 return builtinCall(gz, scope, rl, node, &params);
651651 }
652652 },
......@@ -656,7 +656,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
656656 },
657657
658658 .call_one, .call_one_comma, .async_call_one, .async_call_one_comma => {
659 var params: [1]ast.Node.Index = undefined;
659 var params: [1]Ast.Node.Index = undefined;
660660 return callExpr(gz, scope, rl, node, tree.callOne(&params, node));
661661 },
662662 .call, .call_comma, .async_call, .async_call_comma => {
......@@ -704,7 +704,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
704704 },
705705 .slice => {
706706 const lhs = try expr(gz, scope, .ref, node_datas[node].lhs);
707 const extra = tree.extraData(node_datas[node].rhs, ast.Node.Slice);
707 const extra = tree.extraData(node_datas[node].rhs, Ast.Node.Slice);
708708 const start = try expr(gz, scope, .{ .ty = .usize_type }, extra.start);
709709 const end = try expr(gz, scope, .{ .ty = .usize_type }, extra.end);
710710 const result = try gz.addPlNode(.slice_end, node, Zir.Inst.SliceEnd{
......@@ -722,7 +722,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
722722 },
723723 .slice_sentinel => {
724724 const lhs = try expr(gz, scope, .ref, node_datas[node].lhs);
725 const extra = tree.extraData(node_datas[node].rhs, ast.Node.SliceSentinel);
725 const extra = tree.extraData(node_datas[node].rhs, Ast.Node.SliceSentinel);
726726 const start = try expr(gz, scope, .{ .ty = .usize_type }, extra.start);
727727 const end = if (extra.end != 0) try expr(gz, scope, .{ .ty = .usize_type }, extra.end) else .none;
728728 const sentinel = try expr(gz, scope, .{ .ty = .usize_type }, extra.sentinel);
......@@ -773,7 +773,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
773773 ), node),
774774 },
775775 .block_two, .block_two_semicolon => {
776 const statements = [2]ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs };
776 const statements = [2]Ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs };
777777 if (node_datas[node].lhs == 0) {
778778 return blockExpr(gz, scope, rl, node, statements[0..0]);
779779 } else if (node_datas[node].rhs == 0) {
......@@ -796,7 +796,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
796796 },
797797 .@"catch" => {
798798 const catch_token = main_tokens[node];
799 const payload_token: ?ast.TokenIndex = if (token_tags[catch_token + 1] == .pipe)
799 const payload_token: ?Ast.TokenIndex = if (token_tags[catch_token + 1] == .pipe)
800800 catch_token + 2
801801 else
802802 null;
......@@ -863,7 +863,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
863863 .container_decl_trailing,
864864 => return containerDecl(gz, scope, rl, node, tree.containerDecl(node)),
865865 .container_decl_two, .container_decl_two_trailing => {
866 var buffer: [2]ast.Node.Index = undefined;
866 var buffer: [2]Ast.Node.Index = undefined;
867867 return containerDecl(gz, scope, rl, node, tree.containerDeclTwo(&buffer, node));
868868 },
869869 .container_decl_arg,
......@@ -874,7 +874,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
874874 .tagged_union_trailing,
875875 => return containerDecl(gz, scope, rl, node, tree.taggedUnion(node)),
876876 .tagged_union_two, .tagged_union_two_trailing => {
877 var buffer: [2]ast.Node.Index = undefined;
877 var buffer: [2]Ast.Node.Index = undefined;
878878 return containerDecl(gz, scope, rl, node, tree.taggedUnionTwo(&buffer, node));
879879 },
880880 .tagged_union_enum_tag,
......@@ -900,11 +900,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
900900 .@"try" => return tryExpr(gz, scope, rl, node, node_datas[node].lhs),
901901
902902 .array_init_one, .array_init_one_comma => {
903 var elements: [1]ast.Node.Index = undefined;
903 var elements: [1]Ast.Node.Index = undefined;
904904 return arrayInitExpr(gz, scope, rl, node, tree.arrayInitOne(&elements, node));
905905 },
906906 .array_init_dot_two, .array_init_dot_two_comma => {
907 var elements: [2]ast.Node.Index = undefined;
907 var elements: [2]Ast.Node.Index = undefined;
908908 return arrayInitExpr(gz, scope, rl, node, tree.arrayInitDotTwo(&elements, node));
909909 },
910910 .array_init_dot,
......@@ -915,11 +915,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
915915 => return arrayInitExpr(gz, scope, rl, node, tree.arrayInit(node)),
916916
917917 .struct_init_one, .struct_init_one_comma => {
918 var fields: [1]ast.Node.Index = undefined;
918 var fields: [1]Ast.Node.Index = undefined;
919919 return structInitExpr(gz, scope, rl, node, tree.structInitOne(&fields, node));
920920 },
921921 .struct_init_dot_two, .struct_init_dot_two_comma => {
922 var fields: [2]ast.Node.Index = undefined;
922 var fields: [2]Ast.Node.Index = undefined;
923923 return structInitExpr(gz, scope, rl, node, tree.structInitDotTwo(&fields, node));
924924 },
925925 .struct_init_dot,
......@@ -930,14 +930,14 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
930930 => return structInitExpr(gz, scope, rl, node, tree.structInit(node)),
931931
932932 .fn_proto_simple => {
933 var params: [1]ast.Node.Index = undefined;
933 var params: [1]Ast.Node.Index = undefined;
934934 return fnProtoExpr(gz, scope, rl, tree.fnProtoSimple(&params, node));
935935 },
936936 .fn_proto_multi => {
937937 return fnProtoExpr(gz, scope, rl, tree.fnProtoMulti(node));
938938 },
939939 .fn_proto_one => {
940 var params: [1]ast.Node.Index = undefined;
940 var params: [1]Ast.Node.Index = undefined;
941941 return fnProtoExpr(gz, scope, rl, tree.fnProtoOne(&params, node));
942942 },
943943 .fn_proto => {
......@@ -950,7 +950,7 @@ fn nosuspendExpr(
950950 gz: *GenZir,
951951 scope: *Scope,
952952 rl: ResultLoc,
953 node: ast.Node.Index,
953 node: Ast.Node.Index,
954954) InnerError!Zir.Inst.Ref {
955955 const astgen = gz.astgen;
956956 const tree = astgen.tree;
......@@ -971,7 +971,7 @@ fn nosuspendExpr(
971971fn suspendExpr(
972972 gz: *GenZir,
973973 scope: *Scope,
974 node: ast.Node.Index,
974 node: Ast.Node.Index,
975975) InnerError!Zir.Inst.Ref {
976976 const astgen = gz.astgen;
977977 const gpa = astgen.gpa;
......@@ -1011,7 +1011,7 @@ fn awaitExpr(
10111011 gz: *GenZir,
10121012 scope: *Scope,
10131013 rl: ResultLoc,
1014 node: ast.Node.Index,
1014 node: Ast.Node.Index,
10151015) InnerError!Zir.Inst.Ref {
10161016 const astgen = gz.astgen;
10171017 const tree = astgen.tree;
......@@ -1033,7 +1033,7 @@ fn resumeExpr(
10331033 gz: *GenZir,
10341034 scope: *Scope,
10351035 rl: ResultLoc,
1036 node: ast.Node.Index,
1036 node: Ast.Node.Index,
10371037) InnerError!Zir.Inst.Ref {
10381038 const astgen = gz.astgen;
10391039 const tree = astgen.tree;
......@@ -1048,7 +1048,7 @@ fn fnProtoExpr(
10481048 gz: *GenZir,
10491049 scope: *Scope,
10501050 rl: ResultLoc,
1051 fn_proto: ast.full.FnProto,
1051 fn_proto: Ast.full.FnProto,
10521052) InnerError!Zir.Inst.Ref {
10531053 const astgen = gz.astgen;
10541054 const gpa = astgen.gpa;
......@@ -1159,8 +1159,8 @@ fn arrayInitExpr(
11591159 gz: *GenZir,
11601160 scope: *Scope,
11611161 rl: ResultLoc,
1162 node: ast.Node.Index,
1163 array_init: ast.full.ArrayInit,
1162 node: Ast.Node.Index,
1163 array_init: Ast.full.ArrayInit,
11641164) InnerError!Zir.Inst.Ref {
11651165 const astgen = gz.astgen;
11661166 const tree = astgen.tree;
......@@ -1179,7 +1179,7 @@ fn arrayInitExpr(
11791179 };
11801180
11811181 infer: {
1182 const array_type: ast.full.ArrayType = switch (node_tags[array_init.ast.type_expr]) {
1182 const array_type: Ast.full.ArrayType = switch (node_tags[array_init.ast.type_expr]) {
11831183 .array_type => tree.arrayType(array_init.ast.type_expr),
11841184 .array_type_sentinel => tree.arrayTypeSentinel(array_init.ast.type_expr),
11851185 else => break :infer,
......@@ -1256,8 +1256,8 @@ fn arrayInitExpr(
12561256fn arrayInitExprRlNone(
12571257 gz: *GenZir,
12581258 scope: *Scope,
1259 node: ast.Node.Index,
1260 elements: []const ast.Node.Index,
1259 node: Ast.Node.Index,
1260 elements: []const Ast.Node.Index,
12611261 tag: Zir.Inst.Tag,
12621262) InnerError!Zir.Inst.Ref {
12631263 const astgen = gz.astgen;
......@@ -1278,8 +1278,8 @@ fn arrayInitExprRlNone(
12781278fn arrayInitExprRlTy(
12791279 gz: *GenZir,
12801280 scope: *Scope,
1281 node: ast.Node.Index,
1282 elements: []const ast.Node.Index,
1281 node: Ast.Node.Index,
1282 elements: []const Ast.Node.Index,
12831283 elem_ty_inst: Zir.Inst.Ref,
12841284 tag: Zir.Inst.Tag,
12851285) InnerError!Zir.Inst.Ref {
......@@ -1304,8 +1304,8 @@ fn arrayInitExprRlTy(
13041304fn arrayInitExprRlPtr(
13051305 gz: *GenZir,
13061306 scope: *Scope,
1307 node: ast.Node.Index,
1308 elements: []const ast.Node.Index,
1307 node: Ast.Node.Index,
1308 elements: []const Ast.Node.Index,
13091309 result_ptr: Zir.Inst.Ref,
13101310) InnerError!Zir.Inst.Ref {
13111311 const astgen = gz.astgen;
......@@ -1334,8 +1334,8 @@ fn structInitExpr(
13341334 gz: *GenZir,
13351335 scope: *Scope,
13361336 rl: ResultLoc,
1337 node: ast.Node.Index,
1338 struct_init: ast.full.StructInit,
1337 node: Ast.Node.Index,
1338 struct_init: Ast.full.StructInit,
13391339) InnerError!Zir.Inst.Ref {
13401340 const astgen = gz.astgen;
13411341 const tree = astgen.tree;
......@@ -1347,7 +1347,7 @@ fn structInitExpr(
13471347 } else array: {
13481348 const node_tags = tree.nodes.items(.tag);
13491349 const main_tokens = tree.nodes.items(.main_token);
1350 const array_type: ast.full.ArrayType = switch (node_tags[struct_init.ast.type_expr]) {
1350 const array_type: Ast.full.ArrayType = switch (node_tags[struct_init.ast.type_expr]) {
13511351 .array_type => tree.arrayType(struct_init.ast.type_expr),
13521352 .array_type_sentinel => tree.arrayTypeSentinel(struct_init.ast.type_expr),
13531353 else => break :array,
......@@ -1420,8 +1420,8 @@ fn structInitExpr(
14201420fn structInitExprRlNone(
14211421 gz: *GenZir,
14221422 scope: *Scope,
1423 node: ast.Node.Index,
1424 struct_init: ast.full.StructInit,
1423 node: Ast.Node.Index,
1424 struct_init: Ast.full.StructInit,
14251425 tag: Zir.Inst.Tag,
14261426) InnerError!Zir.Inst.Ref {
14271427 const astgen = gz.astgen;
......@@ -1454,8 +1454,8 @@ fn structInitExprRlNone(
14541454fn structInitExprRlPtr(
14551455 gz: *GenZir,
14561456 scope: *Scope,
1457 node: ast.Node.Index,
1458 struct_init: ast.full.StructInit,
1457 node: Ast.Node.Index,
1458 struct_init: Ast.full.StructInit,
14591459 result_ptr: Zir.Inst.Ref,
14601460) InnerError!Zir.Inst.Ref {
14611461 const astgen = gz.astgen;
......@@ -1488,8 +1488,8 @@ fn structInitExprRlPtr(
14881488fn structInitExprRlTy(
14891489 gz: *GenZir,
14901490 scope: *Scope,
1491 node: ast.Node.Index,
1492 struct_init: ast.full.StructInit,
1491 node: Ast.Node.Index,
1492 struct_init: Ast.full.StructInit,
14931493 ty_inst: Zir.Inst.Ref,
14941494 tag: Zir.Inst.Tag,
14951495) InnerError!Zir.Inst.Ref {
......@@ -1530,7 +1530,7 @@ fn comptimeExpr(
15301530 gz: *GenZir,
15311531 scope: *Scope,
15321532 rl: ResultLoc,
1533 node: ast.Node.Index,
1533 node: Ast.Node.Index,
15341534) InnerError!Zir.Inst.Ref {
15351535 const prev_force_comptime = gz.force_comptime;
15361536 gz.force_comptime = true;
......@@ -1546,7 +1546,7 @@ fn comptimeExprAst(
15461546 gz: *GenZir,
15471547 scope: *Scope,
15481548 rl: ResultLoc,
1549 node: ast.Node.Index,
1549 node: Ast.Node.Index,
15501550) InnerError!Zir.Inst.Ref {
15511551 const astgen = gz.astgen;
15521552 if (gz.force_comptime) {
......@@ -1561,7 +1561,7 @@ fn comptimeExprAst(
15611561 return result;
15621562}
15631563
1564fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref {
1564fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
15651565 const astgen = parent_gz.astgen;
15661566 const tree = astgen.tree;
15671567 const node_datas = tree.nodes.items(.data);
......@@ -1636,7 +1636,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn
16361636 }
16371637}
16381638
1639fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref {
1639fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
16401640 const astgen = parent_gz.astgen;
16411641 const tree = astgen.tree;
16421642 const node_datas = tree.nodes.items(.data);
......@@ -1694,8 +1694,8 @@ fn blockExpr(
16941694 gz: *GenZir,
16951695 scope: *Scope,
16961696 rl: ResultLoc,
1697 block_node: ast.Node.Index,
1698 statements: []const ast.Node.Index,
1697 block_node: Ast.Node.Index,
1698 statements: []const Ast.Node.Index,
16991699) InnerError!Zir.Inst.Ref {
17001700 const tracy = trace(@src());
17011701 defer tracy.end();
......@@ -1716,7 +1716,7 @@ fn blockExpr(
17161716 return rvalue(gz, rl, .void_value, block_node);
17171717}
17181718
1719fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: ast.TokenIndex) !void {
1719fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: Ast.TokenIndex) !void {
17201720 // Look for the label in the scope.
17211721 var scope = parent_scope;
17221722 while (true) {
......@@ -1752,8 +1752,8 @@ fn labeledBlockExpr(
17521752 gz: *GenZir,
17531753 parent_scope: *Scope,
17541754 rl: ResultLoc,
1755 block_node: ast.Node.Index,
1756 statements: []const ast.Node.Index,
1755 block_node: Ast.Node.Index,
1756 statements: []const Ast.Node.Index,
17571757 zir_tag: Zir.Inst.Tag,
17581758) InnerError!Zir.Inst.Ref {
17591759 const tracy = trace(@src());
......@@ -1829,7 +1829,7 @@ fn labeledBlockExpr(
18291829 }
18301830}
18311831
1832fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Node.Index) !void {
1832fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Node.Index) !void {
18331833 const astgen = gz.astgen;
18341834 const tree = astgen.tree;
18351835 const node_tags = tree.nodes.items(.tag);
......@@ -1837,7 +1837,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod
18371837 var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa);
18381838 defer block_arena.deinit();
18391839
1840 var noreturn_src_node: ast.Node.Index = 0;
1840 var noreturn_src_node: Ast.Node.Index = 0;
18411841 var scope = parent_scope;
18421842 for (statements) |statement| {
18431843 if (noreturn_src_node != 0) {
......@@ -1892,12 +1892,12 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod
18921892
18931893/// Returns AST source node of the thing that is noreturn if the statement is definitely `noreturn`.
18941894/// Otherwise returns 0.
1895fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) InnerError!ast.Node.Index {
1895fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) InnerError!Ast.Node.Index {
18961896 try emitDbgNode(gz, statement);
18971897 // We need to emit an error if the result is not `noreturn` or `void`, but
18981898 // we want to avoid adding the ZIR instruction if possible for performance.
18991899 const maybe_unused_result = try expr(gz, scope, .none, statement);
1900 var noreturn_src_node: ast.Node.Index = 0;
1900 var noreturn_src_node: Ast.Node.Index = 0;
19011901 const elide_check = if (refToIndex(maybe_unused_result)) |inst| b: {
19021902 // Note that this array becomes invalid after appending more items to it
19031903 // in the above while loop.
......@@ -2344,7 +2344,7 @@ fn checkUsed(
23442344
23452345fn makeDeferScope(
23462346 scope: *Scope,
2347 node: ast.Node.Index,
2347 node: Ast.Node.Index,
23482348 block_arena: *Allocator,
23492349 scope_tag: Scope.Tag,
23502350) InnerError!*Scope {
......@@ -2360,9 +2360,9 @@ fn makeDeferScope(
23602360fn varDecl(
23612361 gz: *GenZir,
23622362 scope: *Scope,
2363 node: ast.Node.Index,
2363 node: Ast.Node.Index,
23642364 block_arena: *Allocator,
2365 var_decl: ast.full.VarDecl,
2365 var_decl: Ast.full.VarDecl,
23662366) InnerError!*Scope {
23672367 try emitDbgNode(gz, node);
23682368 const astgen = gz.astgen;
......@@ -2574,7 +2574,7 @@ fn varDecl(
25742574 }
25752575}
25762576
2577fn emitDbgNode(gz: *GenZir, node: ast.Node.Index) !void {
2577fn emitDbgNode(gz: *GenZir, node: Ast.Node.Index) !void {
25782578 // The instruction emitted here is for debugging runtime code.
25792579 // If the current block will be evaluated only during semantic analysis
25802580 // then no dbg_stmt ZIR instruction is needed.
......@@ -2598,7 +2598,7 @@ fn emitDbgNode(gz: *GenZir, node: ast.Node.Index) !void {
25982598 } });
25992599}
26002600
2601fn assign(gz: *GenZir, scope: *Scope, infix_node: ast.Node.Index) InnerError!void {
2601fn assign(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerError!void {
26022602 try emitDbgNode(gz, infix_node);
26032603 const astgen = gz.astgen;
26042604 const tree = astgen.tree;
......@@ -2623,7 +2623,7 @@ fn assign(gz: *GenZir, scope: *Scope, infix_node: ast.Node.Index) InnerError!voi
26232623fn assignOp(
26242624 gz: *GenZir,
26252625 scope: *Scope,
2626 infix_node: ast.Node.Index,
2626 infix_node: Ast.Node.Index,
26272627 op_inst_tag: Zir.Inst.Tag,
26282628) InnerError!void {
26292629 try emitDbgNode(gz, infix_node);
......@@ -2646,7 +2646,7 @@ fn assignOp(
26462646fn assignShift(
26472647 gz: *GenZir,
26482648 scope: *Scope,
2649 infix_node: ast.Node.Index,
2649 infix_node: Ast.Node.Index,
26502650 op_inst_tag: Zir.Inst.Tag,
26512651) InnerError!void {
26522652 try emitDbgNode(gz, infix_node);
......@@ -2666,7 +2666,7 @@ fn assignShift(
26662666 _ = try gz.addBin(.store, lhs_ptr, result);
26672667}
26682668
2669fn boolNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref {
2669fn boolNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
26702670 const astgen = gz.astgen;
26712671 const tree = astgen.tree;
26722672 const node_datas = tree.nodes.items(.data);
......@@ -2676,7 +2676,7 @@ fn boolNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inne
26762676 return rvalue(gz, rl, result, node);
26772677}
26782678
2679fn bitNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref {
2679fn bitNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
26802680 const astgen = gz.astgen;
26812681 const tree = astgen.tree;
26822682 const node_datas = tree.nodes.items(.data);
......@@ -2690,7 +2690,7 @@ fn negation(
26902690 gz: *GenZir,
26912691 scope: *Scope,
26922692 rl: ResultLoc,
2693 node: ast.Node.Index,
2693 node: Ast.Node.Index,
26942694 tag: Zir.Inst.Tag,
26952695) InnerError!Zir.Inst.Ref {
26962696 const astgen = gz.astgen;
......@@ -2706,8 +2706,8 @@ fn ptrType(
27062706 gz: *GenZir,
27072707 scope: *Scope,
27082708 rl: ResultLoc,
2709 node: ast.Node.Index,
2710 ptr_info: ast.full.PtrType,
2709 node: Ast.Node.Index,
2710 ptr_info: Ast.full.PtrType,
27112711) InnerError!Zir.Inst.Ref {
27122712 const elem_type = try typeExpr(gz, scope, ptr_info.ast.child_type);
27132713
......@@ -2788,7 +2788,7 @@ fn ptrType(
27882788 return rvalue(gz, rl, result, node);
27892789}
27902790
2791fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !Zir.Inst.Ref {
2791fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) !Zir.Inst.Ref {
27922792 const astgen = gz.astgen;
27932793 const tree = astgen.tree;
27942794 const node_datas = tree.nodes.items(.data);
......@@ -2808,13 +2808,13 @@ fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !Z
28082808 return rvalue(gz, rl, result, node);
28092809}
28102810
2811fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !Zir.Inst.Ref {
2811fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) !Zir.Inst.Ref {
28122812 const astgen = gz.astgen;
28132813 const tree = astgen.tree;
28142814 const node_datas = tree.nodes.items(.data);
28152815 const node_tags = tree.nodes.items(.tag);
28162816 const main_tokens = tree.nodes.items(.main_token);
2817 const extra = tree.extraData(node_datas[node].rhs, ast.Node.ArrayTypeSentinel);
2817 const extra = tree.extraData(node_datas[node].rhs, Ast.Node.ArrayTypeSentinel);
28182818
28192819 const len_node = node_datas[node].lhs;
28202820 if (node_tags[len_node] == .identifier and
......@@ -2870,9 +2870,9 @@ fn fnDecl(
28702870 gz: *GenZir,
28712871 scope: *Scope,
28722872 wip_decls: *WipDecls,
2873 decl_node: ast.Node.Index,
2874 body_node: ast.Node.Index,
2875 fn_proto: ast.full.FnProto,
2873 decl_node: Ast.Node.Index,
2874 body_node: Ast.Node.Index,
2875 fn_proto: Ast.full.FnProto,
28762876) InnerError!void {
28772877 const gpa = astgen.gpa;
28782878 const tree = astgen.tree;
......@@ -3135,8 +3135,8 @@ fn globalVarDecl(
31353135 gz: *GenZir,
31363136 scope: *Scope,
31373137 wip_decls: *WipDecls,
3138 node: ast.Node.Index,
3139 var_decl: ast.full.VarDecl,
3138 node: Ast.Node.Index,
3139 var_decl: Ast.full.VarDecl,
31403140) InnerError!void {
31413141 const gpa = astgen.gpa;
31423142 const tree = astgen.tree;
......@@ -3279,7 +3279,7 @@ fn comptimeDecl(
32793279 gz: *GenZir,
32803280 scope: *Scope,
32813281 wip_decls: *WipDecls,
3282 node: ast.Node.Index,
3282 node: Ast.Node.Index,
32833283) InnerError!void {
32843284 const gpa = astgen.gpa;
32853285 const tree = astgen.tree;
......@@ -3326,7 +3326,7 @@ fn usingnamespaceDecl(
33263326 gz: *GenZir,
33273327 scope: *Scope,
33283328 wip_decls: *WipDecls,
3329 node: ast.Node.Index,
3329 node: Ast.Node.Index,
33303330) InnerError!void {
33313331 const gpa = astgen.gpa;
33323332 const tree = astgen.tree;
......@@ -3377,7 +3377,7 @@ fn testDecl(
33773377 gz: *GenZir,
33783378 scope: *Scope,
33793379 wip_decls: *WipDecls,
3380 node: ast.Node.Index,
3380 node: Ast.Node.Index,
33813381) InnerError!void {
33823382 const gpa = astgen.gpa;
33833383 const tree = astgen.tree;
......@@ -3468,8 +3468,8 @@ fn testDecl(
34683468fn structDeclInner(
34693469 gz: *GenZir,
34703470 scope: *Scope,
3471 node: ast.Node.Index,
3472 container_decl: ast.full.ContainerDecl,
3471 node: Ast.Node.Index,
3472 container_decl: Ast.full.ContainerDecl,
34733473 layout: std.builtin.TypeInfo.ContainerLayout,
34743474) InnerError!Zir.Inst.Ref {
34753475 if (container_decl.ast.members.len == 0) {
......@@ -3537,7 +3537,7 @@ fn structDeclInner(
35373537 const body = node_datas[member_node].rhs;
35383538 switch (node_tags[fn_proto]) {
35393539 .fn_proto_simple => {
3540 var params: [1]ast.Node.Index = undefined;
3540 var params: [1]Ast.Node.Index = undefined;
35413541 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
35423542 error.OutOfMemory => return error.OutOfMemory,
35433543 error.AnalysisFail => {},
......@@ -3552,7 +3552,7 @@ fn structDeclInner(
35523552 continue;
35533553 },
35543554 .fn_proto_one => {
3555 var params: [1]ast.Node.Index = undefined;
3555 var params: [1]Ast.Node.Index = undefined;
35563556 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
35573557 error.OutOfMemory => return error.OutOfMemory,
35583558 error.AnalysisFail => {},
......@@ -3570,7 +3570,7 @@ fn structDeclInner(
35703570 }
35713571 },
35723572 .fn_proto_simple => {
3573 var params: [1]ast.Node.Index = undefined;
3573 var params: [1]Ast.Node.Index = undefined;
35743574 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
35753575 error.OutOfMemory => return error.OutOfMemory,
35763576 error.AnalysisFail => {},
......@@ -3585,7 +3585,7 @@ fn structDeclInner(
35853585 continue;
35863586 },
35873587 .fn_proto_one => {
3588 var params: [1]ast.Node.Index = undefined;
3588 var params: [1]Ast.Node.Index = undefined;
35893589 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
35903590 error.OutOfMemory => return error.OutOfMemory,
35913591 error.AnalysisFail => {},
......@@ -3750,10 +3750,10 @@ fn structDeclInner(
37503750fn unionDeclInner(
37513751 gz: *GenZir,
37523752 scope: *Scope,
3753 node: ast.Node.Index,
3754 members: []const ast.Node.Index,
3753 node: Ast.Node.Index,
3754 members: []const Ast.Node.Index,
37553755 layout: std.builtin.TypeInfo.ContainerLayout,
3756 arg_node: ast.Node.Index,
3756 arg_node: Ast.Node.Index,
37573757 have_auto_enum: bool,
37583758) InnerError!Zir.Inst.Ref {
37593759 const astgen = gz.astgen;
......@@ -3812,7 +3812,7 @@ fn unionDeclInner(
38123812 const body = node_datas[member_node].rhs;
38133813 switch (node_tags[fn_proto]) {
38143814 .fn_proto_simple => {
3815 var params: [1]ast.Node.Index = undefined;
3815 var params: [1]Ast.Node.Index = undefined;
38163816 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
38173817 error.OutOfMemory => return error.OutOfMemory,
38183818 error.AnalysisFail => {},
......@@ -3827,7 +3827,7 @@ fn unionDeclInner(
38273827 continue;
38283828 },
38293829 .fn_proto_one => {
3830 var params: [1]ast.Node.Index = undefined;
3830 var params: [1]Ast.Node.Index = undefined;
38313831 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
38323832 error.OutOfMemory => return error.OutOfMemory,
38333833 error.AnalysisFail => {},
......@@ -3845,7 +3845,7 @@ fn unionDeclInner(
38453845 }
38463846 },
38473847 .fn_proto_simple => {
3848 var params: [1]ast.Node.Index = undefined;
3848 var params: [1]Ast.Node.Index = undefined;
38493849 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
38503850 error.OutOfMemory => return error.OutOfMemory,
38513851 error.AnalysisFail => {},
......@@ -3860,7 +3860,7 @@ fn unionDeclInner(
38603860 continue;
38613861 },
38623862 .fn_proto_one => {
3863 var params: [1]ast.Node.Index = undefined;
3863 var params: [1]Ast.Node.Index = undefined;
38643864 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
38653865 error.OutOfMemory => return error.OutOfMemory,
38663866 error.AnalysisFail => {},
......@@ -4033,8 +4033,8 @@ fn containerDecl(
40334033 gz: *GenZir,
40344034 scope: *Scope,
40354035 rl: ResultLoc,
4036 node: ast.Node.Index,
4037 container_decl: ast.full.ContainerDecl,
4036 node: Ast.Node.Index,
4037 container_decl: Ast.full.ContainerDecl,
40384038) InnerError!Zir.Inst.Ref {
40394039 const astgen = gz.astgen;
40404040 const gpa = astgen.gpa;
......@@ -4084,7 +4084,7 @@ fn containerDecl(
40844084 var values: usize = 0;
40854085 var total_fields: usize = 0;
40864086 var decls: usize = 0;
4087 var nonexhaustive_node: ast.Node.Index = 0;
4087 var nonexhaustive_node: Ast.Node.Index = 0;
40884088 for (container_decl.ast.members) |member_node| {
40894089 const member = switch (node_tags[member_node]) {
40904090 .container_field_init => tree.containerFieldInit(member_node),
......@@ -4225,7 +4225,7 @@ fn containerDecl(
42254225 const body = node_datas[member_node].rhs;
42264226 switch (node_tags[fn_proto]) {
42274227 .fn_proto_simple => {
4228 var params: [1]ast.Node.Index = undefined;
4228 var params: [1]Ast.Node.Index = undefined;
42294229 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
42304230 error.OutOfMemory => return error.OutOfMemory,
42314231 error.AnalysisFail => {},
......@@ -4240,7 +4240,7 @@ fn containerDecl(
42404240 continue;
42414241 },
42424242 .fn_proto_one => {
4243 var params: [1]ast.Node.Index = undefined;
4243 var params: [1]Ast.Node.Index = undefined;
42444244 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
42454245 error.OutOfMemory => return error.OutOfMemory,
42464246 error.AnalysisFail => {},
......@@ -4258,7 +4258,7 @@ fn containerDecl(
42584258 }
42594259 },
42604260 .fn_proto_simple => {
4261 var params: [1]ast.Node.Index = undefined;
4261 var params: [1]Ast.Node.Index = undefined;
42624262 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
42634263 error.OutOfMemory => return error.OutOfMemory,
42644264 error.AnalysisFail => {},
......@@ -4273,7 +4273,7 @@ fn containerDecl(
42734273 continue;
42744274 },
42754275 .fn_proto_one => {
4276 var params: [1]ast.Node.Index = undefined;
4276 var params: [1]Ast.Node.Index = undefined;
42774277 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
42784278 error.OutOfMemory => return error.OutOfMemory,
42794279 error.AnalysisFail => {},
......@@ -4441,7 +4441,7 @@ fn containerDecl(
44414441 const body = node_datas[member_node].rhs;
44424442 switch (node_tags[fn_proto]) {
44434443 .fn_proto_simple => {
4444 var params: [1]ast.Node.Index = undefined;
4444 var params: [1]Ast.Node.Index = undefined;
44454445 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
44464446 error.OutOfMemory => return error.OutOfMemory,
44474447 error.AnalysisFail => {},
......@@ -4456,7 +4456,7 @@ fn containerDecl(
44564456 continue;
44574457 },
44584458 .fn_proto_one => {
4459 var params: [1]ast.Node.Index = undefined;
4459 var params: [1]Ast.Node.Index = undefined;
44604460 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
44614461 error.OutOfMemory => return error.OutOfMemory,
44624462 error.AnalysisFail => {},
......@@ -4474,7 +4474,7 @@ fn containerDecl(
44744474 }
44754475 },
44764476 .fn_proto_simple => {
4477 var params: [1]ast.Node.Index = undefined;
4477 var params: [1]Ast.Node.Index = undefined;
44784478 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
44794479 error.OutOfMemory => return error.OutOfMemory,
44804480 error.AnalysisFail => {},
......@@ -4489,7 +4489,7 @@ fn containerDecl(
44894489 continue;
44904490 },
44914491 .fn_proto_one => {
4492 var params: [1]ast.Node.Index = undefined;
4492 var params: [1]Ast.Node.Index = undefined;
44934493 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
44944494 error.OutOfMemory => return error.OutOfMemory,
44954495 error.AnalysisFail => {},
......@@ -4590,7 +4590,7 @@ fn containerDecl(
45904590 }
45914591}
45924592
4593fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref {
4593fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
45944594 const astgen = gz.astgen;
45954595 const gpa = astgen.gpa;
45964596 const tree = astgen.tree;
......@@ -4629,8 +4629,8 @@ fn tryExpr(
46294629 parent_gz: *GenZir,
46304630 scope: *Scope,
46314631 rl: ResultLoc,
4632 node: ast.Node.Index,
4633 operand_node: ast.Node.Index,
4632 node: Ast.Node.Index,
4633 operand_node: Ast.Node.Index,
46344634) InnerError!Zir.Inst.Ref {
46354635 const astgen = parent_gz.astgen;
46364636
......@@ -4705,13 +4705,13 @@ fn orelseCatchExpr(
47054705 parent_gz: *GenZir,
47064706 scope: *Scope,
47074707 rl: ResultLoc,
4708 node: ast.Node.Index,
4709 lhs: ast.Node.Index,
4708 node: Ast.Node.Index,
4709 lhs: Ast.Node.Index,
47104710 cond_op: Zir.Inst.Tag,
47114711 unwrap_op: Zir.Inst.Tag,
47124712 unwrap_code_op: Zir.Inst.Tag,
4713 rhs: ast.Node.Index,
4714 payload_token: ?ast.TokenIndex,
4713 rhs: Ast.Node.Index,
4714 payload_token: ?Ast.TokenIndex,
47154715) InnerError!Zir.Inst.Ref {
47164716 const astgen = parent_gz.astgen;
47174717 const tree = astgen.tree;
......@@ -4796,7 +4796,7 @@ fn orelseCatchExpr(
47964796fn finishThenElseBlock(
47974797 parent_gz: *GenZir,
47984798 rl: ResultLoc,
4799 node: ast.Node.Index,
4799 node: Ast.Node.Index,
48004800 block_scope: *GenZir,
48014801 then_scope: *GenZir,
48024802 else_scope: *GenZir,
......@@ -4852,7 +4852,7 @@ fn finishThenElseBlock(
48524852/// tokens without allocating.
48534853/// OK in theory it could do it without allocating. This implementation
48544854/// allocates when the @"" form is used.
4855fn tokenIdentEql(astgen: *AstGen, token1: ast.TokenIndex, token2: ast.TokenIndex) !bool {
4855fn tokenIdentEql(astgen: *AstGen, token1: Ast.TokenIndex, token2: Ast.TokenIndex) !bool {
48564856 const ident_name_1 = try astgen.identifierTokenString(token1);
48574857 const ident_name_2 = try astgen.identifierTokenString(token2);
48584858 return mem.eql(u8, ident_name_1, ident_name_2);
......@@ -4862,7 +4862,7 @@ fn fieldAccess(
48624862 gz: *GenZir,
48634863 scope: *Scope,
48644864 rl: ResultLoc,
4865 node: ast.Node.Index,
4865 node: Ast.Node.Index,
48664866) InnerError!Zir.Inst.Ref {
48674867 const astgen = gz.astgen;
48684868 const tree = astgen.tree;
......@@ -4889,7 +4889,7 @@ fn arrayAccess(
48894889 gz: *GenZir,
48904890 scope: *Scope,
48914891 rl: ResultLoc,
4892 node: ast.Node.Index,
4892 node: Ast.Node.Index,
48934893) InnerError!Zir.Inst.Ref {
48944894 const astgen = gz.astgen;
48954895 const tree = astgen.tree;
......@@ -4912,7 +4912,7 @@ fn simpleBinOp(
49124912 gz: *GenZir,
49134913 scope: *Scope,
49144914 rl: ResultLoc,
4915 node: ast.Node.Index,
4915 node: Ast.Node.Index,
49164916 op_inst_tag: Zir.Inst.Tag,
49174917) InnerError!Zir.Inst.Ref {
49184918 const astgen = gz.astgen;
......@@ -4929,8 +4929,8 @@ fn simpleBinOp(
49294929fn simpleStrTok(
49304930 gz: *GenZir,
49314931 rl: ResultLoc,
4932 ident_token: ast.TokenIndex,
4933 node: ast.Node.Index,
4932 ident_token: Ast.TokenIndex,
4933 node: Ast.Node.Index,
49344934 op_inst_tag: Zir.Inst.Tag,
49354935) InnerError!Zir.Inst.Ref {
49364936 const astgen = gz.astgen;
......@@ -4943,7 +4943,7 @@ fn boolBinOp(
49434943 gz: *GenZir,
49444944 scope: *Scope,
49454945 rl: ResultLoc,
4946 node: ast.Node.Index,
4946 node: Ast.Node.Index,
49474947 zir_tag: Zir.Inst.Tag,
49484948) InnerError!Zir.Inst.Ref {
49494949 const astgen = gz.astgen;
......@@ -4969,8 +4969,8 @@ fn ifExpr(
49694969 parent_gz: *GenZir,
49704970 scope: *Scope,
49714971 rl: ResultLoc,
4972 node: ast.Node.Index,
4973 if_full: ast.full.If,
4972 node: Ast.Node.Index,
4973 if_full: Ast.full.If,
49744974) InnerError!Zir.Inst.Ref {
49754975 const astgen = parent_gz.astgen;
49764976 const tree = astgen.tree;
......@@ -5089,7 +5089,7 @@ fn ifExpr(
50895089
50905090 const else_node = if_full.ast.else_expr;
50915091 const else_info: struct {
5092 src: ast.Node.Index,
5092 src: Ast.Node.Index,
50935093 result: Zir.Inst.Ref,
50945094 } = if (else_node != 0) blk: {
50955095 block_scope.break_count += 1;
......@@ -5215,8 +5215,8 @@ fn whileExpr(
52155215 parent_gz: *GenZir,
52165216 scope: *Scope,
52175217 rl: ResultLoc,
5218 node: ast.Node.Index,
5219 while_full: ast.full.While,
5218 node: Ast.Node.Index,
5219 while_full: Ast.full.While,
52205220) InnerError!Zir.Inst.Ref {
52215221 const astgen = parent_gz.astgen;
52225222 const tree = astgen.tree;
......@@ -5368,7 +5368,7 @@ fn whileExpr(
53685368
53695369 const else_node = while_full.ast.else_expr;
53705370 const else_info: struct {
5371 src: ast.Node.Index,
5371 src: Ast.Node.Index,
53725372 result: Zir.Inst.Ref,
53735373 } = if (else_node != 0) blk: {
53745374 loop_scope.break_count += 1;
......@@ -5435,8 +5435,8 @@ fn forExpr(
54355435 parent_gz: *GenZir,
54365436 scope: *Scope,
54375437 rl: ResultLoc,
5438 node: ast.Node.Index,
5439 for_full: ast.full.While,
5438 node: Ast.Node.Index,
5439 for_full: Ast.full.While,
54405440) InnerError!Zir.Inst.Ref {
54415441 const astgen = parent_gz.astgen;
54425442
......@@ -5577,7 +5577,7 @@ fn forExpr(
55775577
55785578 const else_node = for_full.ast.else_expr;
55795579 const else_info: struct {
5580 src: ast.Node.Index,
5580 src: Ast.Node.Index,
55815581 result: Zir.Inst.Ref,
55825582 } = if (else_node != 0) blk: {
55835583 loop_scope.break_count += 1;
......@@ -5618,7 +5618,7 @@ fn switchExpr(
56185618 parent_gz: *GenZir,
56195619 scope: *Scope,
56205620 rl: ResultLoc,
5621 switch_node: ast.Node.Index,
5621 switch_node: Ast.Node.Index,
56225622) InnerError!Zir.Inst.Ref {
56235623 const astgen = parent_gz.astgen;
56245624 const gpa = astgen.gpa;
......@@ -5628,7 +5628,7 @@ fn switchExpr(
56285628 const main_tokens = tree.nodes.items(.main_token);
56295629 const token_tags = tree.tokens.items(.tag);
56305630 const operand_node = node_datas[switch_node].lhs;
5631 const extra = tree.extraData(node_datas[switch_node].rhs, ast.Node.SubRange);
5631 const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange);
56325632 const case_nodes = tree.extra_data[extra.start..extra.end];
56335633
56345634 // We perform two passes over the AST. This first pass is to collect information
......@@ -5638,9 +5638,9 @@ fn switchExpr(
56385638 var scalar_cases_len: u32 = 0;
56395639 var multi_cases_len: u32 = 0;
56405640 var special_prong: Zir.SpecialProng = .none;
5641 var special_node: ast.Node.Index = 0;
5642 var else_src: ?ast.TokenIndex = null;
5643 var underscore_src: ?ast.TokenIndex = null;
5641 var special_node: Ast.Node.Index = 0;
5642 var else_src: ?Ast.TokenIndex = null;
5643 var underscore_src: ?Ast.TokenIndex = null;
56445644 for (case_nodes) |case_node| {
56455645 const case = switch (node_tags[case_node]) {
56465646 .switch_case_one => tree.switchCaseOne(case_node),
......@@ -6212,7 +6212,7 @@ fn switchExpr(
62126212 }
62136213}
62146214
6215fn ret(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref {
6215fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
62166216 const astgen = gz.astgen;
62176217 const tree = astgen.tree;
62186218 const node_datas = tree.nodes.items(.data);
......@@ -6311,7 +6311,7 @@ fn identifier(
63116311 gz: *GenZir,
63126312 scope: *Scope,
63136313 rl: ResultLoc,
6314 ident: ast.Node.Index,
6314 ident: Ast.Node.Index,
63156315) InnerError!Zir.Inst.Ref {
63166316 const tracy = trace(@src());
63176317 defer tracy.end();
......@@ -6363,8 +6363,8 @@ fn identifier(
63636363 // Local variables, including function parameters.
63646364 const name_str_index = try astgen.identAsString(ident_token);
63656365 var s = scope;
6366 var found_already: ?ast.Node.Index = null; // we have found a decl with the same name already
6367 var hit_namespace: ast.Node.Index = 0;
6366 var found_already: ?Ast.Node.Index = null; // we have found a decl with the same name already
6367 var hit_namespace: Ast.Node.Index = 0;
63686368 while (true) switch (s.tag) {
63696369 .local_val => {
63706370 const local_val = s.cast(Scope.LocalVal).?;
......@@ -6434,7 +6434,7 @@ fn identifier(
64346434fn stringLiteral(
64356435 gz: *GenZir,
64366436 rl: ResultLoc,
6437 node: ast.Node.Index,
6437 node: Ast.Node.Index,
64386438) InnerError!Zir.Inst.Ref {
64396439 const astgen = gz.astgen;
64406440 const tree = astgen.tree;
......@@ -6454,7 +6454,7 @@ fn stringLiteral(
64546454fn multilineStringLiteral(
64556455 gz: *GenZir,
64566456 rl: ResultLoc,
6457 node: ast.Node.Index,
6457 node: Ast.Node.Index,
64586458) InnerError!Zir.Inst.Ref {
64596459 const astgen = gz.astgen;
64606460 const str = try astgen.strLitNodeAsString(node);
......@@ -6468,7 +6468,7 @@ fn multilineStringLiteral(
64686468 return rvalue(gz, rl, result, node);
64696469}
64706470
6471fn charLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) !Zir.Inst.Ref {
6471fn charLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) !Zir.Inst.Ref {
64726472 const astgen = gz.astgen;
64736473 const tree = astgen.tree;
64746474 const main_tokens = tree.nodes.items(.main_token);
......@@ -6547,7 +6547,7 @@ fn charLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) !Zir.Inst.Ref {
65476547 }
65486548}
65496549
6550fn integerLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref {
6550fn integerLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
65516551 const astgen = gz.astgen;
65526552 const tree = astgen.tree;
65536553 const main_tokens = tree.nodes.items(.main_token);
......@@ -6593,7 +6593,7 @@ fn integerLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) InnerError!Z
65936593 return rvalue(gz, rl, result, node);
65946594}
65956595
6596fn floatLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref {
6596fn floatLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref {
65976597 const astgen = gz.astgen;
65986598 const tree = astgen.tree;
65996599 const main_tokens = tree.nodes.items(.main_token);
......@@ -6633,8 +6633,8 @@ fn asmExpr(
66336633 gz: *GenZir,
66346634 scope: *Scope,
66356635 rl: ResultLoc,
6636 node: ast.Node.Index,
6637 full: ast.full.Asm,
6636 node: Ast.Node.Index,
6637 full: Ast.full.Asm,
66386638) InnerError!Zir.Inst.Ref {
66396639 const astgen = gz.astgen;
66406640 const tree = astgen.tree;
......@@ -6791,9 +6791,9 @@ fn as(
67916791 gz: *GenZir,
67926792 scope: *Scope,
67936793 rl: ResultLoc,
6794 node: ast.Node.Index,
6795 lhs: ast.Node.Index,
6796 rhs: ast.Node.Index,
6794 node: Ast.Node.Index,
6795 lhs: Ast.Node.Index,
6796 rhs: Ast.Node.Index,
67976797) InnerError!Zir.Inst.Ref {
67986798 const dest_type = try typeExpr(gz, scope, lhs);
67996799 switch (rl) {
......@@ -6814,8 +6814,8 @@ fn unionInit(
68146814 gz: *GenZir,
68156815 scope: *Scope,
68166816 rl: ResultLoc,
6817 node: ast.Node.Index,
6818 params: []const ast.Node.Index,
6817 node: Ast.Node.Index,
6818 params: []const Ast.Node.Index,
68196819) InnerError!Zir.Inst.Ref {
68206820 const union_type = try typeExpr(gz, scope, params[0]);
68216821 const field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]);
......@@ -6840,9 +6840,9 @@ fn unionInit(
68406840fn unionInitRlPtr(
68416841 parent_gz: *GenZir,
68426842 scope: *Scope,
6843 node: ast.Node.Index,
6843 node: Ast.Node.Index,
68446844 result_ptr: Zir.Inst.Ref,
6845 expr_node: ast.Node.Index,
6845 expr_node: Ast.Node.Index,
68466846 union_type: Zir.Inst.Ref,
68476847 field_name: Zir.Inst.Ref,
68486848) InnerError!Zir.Inst.Ref {
......@@ -6859,9 +6859,9 @@ fn asRlPtr(
68596859 parent_gz: *GenZir,
68606860 scope: *Scope,
68616861 rl: ResultLoc,
6862 src_node: ast.Node.Index,
6862 src_node: Ast.Node.Index,
68636863 result_ptr: Zir.Inst.Ref,
6864 operand_node: ast.Node.Index,
6864 operand_node: Ast.Node.Index,
68656865 dest_type: Zir.Inst.Ref,
68666866) InnerError!Zir.Inst.Ref {
68676867 // Detect whether this expr() call goes into rvalue() to store the result into the
......@@ -6899,9 +6899,9 @@ fn bitCast(
68996899 gz: *GenZir,
69006900 scope: *Scope,
69016901 rl: ResultLoc,
6902 node: ast.Node.Index,
6903 lhs: ast.Node.Index,
6904 rhs: ast.Node.Index,
6902 node: Ast.Node.Index,
6903 lhs: Ast.Node.Index,
6904 rhs: Ast.Node.Index,
69056905) InnerError!Zir.Inst.Ref {
69066906 const astgen = gz.astgen;
69076907 const dest_type = try typeExpr(gz, scope, lhs);
......@@ -6929,10 +6929,10 @@ fn bitCast(
69296929fn bitCastRlPtr(
69306930 gz: *GenZir,
69316931 scope: *Scope,
6932 node: ast.Node.Index,
6932 node: Ast.Node.Index,
69336933 dest_type: Zir.Inst.Ref,
69346934 result_ptr: Zir.Inst.Ref,
6935 rhs: ast.Node.Index,
6935 rhs: Ast.Node.Index,
69366936) InnerError!Zir.Inst.Ref {
69376937 const casted_result_ptr = try gz.addPlNode(.bitcast_result_ptr, node, Zir.Inst.Bin{
69386938 .lhs = dest_type,
......@@ -6945,8 +6945,8 @@ fn typeOf(
69456945 gz: *GenZir,
69466946 scope: *Scope,
69476947 rl: ResultLoc,
6948 node: ast.Node.Index,
6949 params: []const ast.Node.Index,
6948 node: Ast.Node.Index,
6949 params: []const Ast.Node.Index,
69506950) InnerError!Zir.Inst.Ref {
69516951 if (params.len < 1) {
69526952 return gz.astgen.failNode(node, "expected at least 1 argument, found 0", .{});
......@@ -6970,8 +6970,8 @@ fn builtinCall(
69706970 gz: *GenZir,
69716971 scope: *Scope,
69726972 rl: ResultLoc,
6973 node: ast.Node.Index,
6974 params: []const ast.Node.Index,
6973 node: Ast.Node.Index,
6974 params: []const Ast.Node.Index,
69756975) InnerError!Zir.Inst.Ref {
69766976 const astgen = gz.astgen;
69776977 const tree = astgen.tree;
......@@ -7463,7 +7463,7 @@ fn builtinCall(
74637463fn simpleNoOpVoid(
74647464 gz: *GenZir,
74657465 rl: ResultLoc,
7466 node: ast.Node.Index,
7466 node: Ast.Node.Index,
74677467 tag: Zir.Inst.Tag,
74687468) InnerError!Zir.Inst.Ref {
74697469 _ = try gz.addNode(tag, node);
......@@ -7474,9 +7474,9 @@ fn hasDeclOrField(
74747474 gz: *GenZir,
74757475 scope: *Scope,
74767476 rl: ResultLoc,
7477 node: ast.Node.Index,
7478 lhs_node: ast.Node.Index,
7479 rhs_node: ast.Node.Index,
7477 node: Ast.Node.Index,
7478 lhs_node: Ast.Node.Index,
7479 rhs_node: Ast.Node.Index,
74807480 tag: Zir.Inst.Tag,
74817481) InnerError!Zir.Inst.Ref {
74827482 const container_type = try typeExpr(gz, scope, lhs_node);
......@@ -7492,9 +7492,9 @@ fn typeCast(
74927492 gz: *GenZir,
74937493 scope: *Scope,
74947494 rl: ResultLoc,
7495 node: ast.Node.Index,
7496 lhs_node: ast.Node.Index,
7497 rhs_node: ast.Node.Index,
7495 node: Ast.Node.Index,
7496 lhs_node: Ast.Node.Index,
7497 rhs_node: Ast.Node.Index,
74987498 tag: Zir.Inst.Tag,
74997499) InnerError!Zir.Inst.Ref {
75007500 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{
......@@ -7508,8 +7508,8 @@ fn simpleUnOpType(
75087508 gz: *GenZir,
75097509 scope: *Scope,
75107510 rl: ResultLoc,
7511 node: ast.Node.Index,
7512 operand_node: ast.Node.Index,
7511 node: Ast.Node.Index,
7512 operand_node: Ast.Node.Index,
75137513 tag: Zir.Inst.Tag,
75147514) InnerError!Zir.Inst.Ref {
75157515 const operand = try typeExpr(gz, scope, operand_node);
......@@ -7521,9 +7521,9 @@ fn simpleUnOp(
75217521 gz: *GenZir,
75227522 scope: *Scope,
75237523 rl: ResultLoc,
7524 node: ast.Node.Index,
7524 node: Ast.Node.Index,
75257525 operand_rl: ResultLoc,
7526 operand_node: ast.Node.Index,
7526 operand_node: Ast.Node.Index,
75277527 tag: Zir.Inst.Tag,
75287528) InnerError!Zir.Inst.Ref {
75297529 const operand = try expr(gz, scope, operand_rl, operand_node);
......@@ -7535,8 +7535,8 @@ fn cmpxchg(
75357535 gz: *GenZir,
75367536 scope: *Scope,
75377537 rl: ResultLoc,
7538 node: ast.Node.Index,
7539 params: []const ast.Node.Index,
7538 node: Ast.Node.Index,
7539 params: []const Ast.Node.Index,
75407540 tag: Zir.Inst.Tag,
75417541) InnerError!Zir.Inst.Ref {
75427542 const int_type = try typeExpr(gz, scope, params[0]);
......@@ -7565,9 +7565,9 @@ fn bitBuiltin(
75657565 gz: *GenZir,
75667566 scope: *Scope,
75677567 rl: ResultLoc,
7568 node: ast.Node.Index,
7569 int_type_node: ast.Node.Index,
7570 operand_node: ast.Node.Index,
7568 node: Ast.Node.Index,
7569 int_type_node: Ast.Node.Index,
7570 operand_node: Ast.Node.Index,
75717571 tag: Zir.Inst.Tag,
75727572) InnerError!Zir.Inst.Ref {
75737573 const int_type = try typeExpr(gz, scope, int_type_node);
......@@ -7580,9 +7580,9 @@ fn divBuiltin(
75807580 gz: *GenZir,
75817581 scope: *Scope,
75827582 rl: ResultLoc,
7583 node: ast.Node.Index,
7584 lhs_node: ast.Node.Index,
7585 rhs_node: ast.Node.Index,
7583 node: Ast.Node.Index,
7584 lhs_node: Ast.Node.Index,
7585 rhs_node: Ast.Node.Index,
75867586 tag: Zir.Inst.Tag,
75877587) InnerError!Zir.Inst.Ref {
75887588 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{
......@@ -7596,8 +7596,8 @@ fn simpleCBuiltin(
75967596 gz: *GenZir,
75977597 scope: *Scope,
75987598 rl: ResultLoc,
7599 node: ast.Node.Index,
7600 operand_node: ast.Node.Index,
7599 node: Ast.Node.Index,
7600 operand_node: Ast.Node.Index,
76017601 tag: Zir.Inst.Extended,
76027602) InnerError!Zir.Inst.Ref {
76037603 const operand = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, operand_node);
......@@ -7612,9 +7612,9 @@ fn offsetOf(
76127612 gz: *GenZir,
76137613 scope: *Scope,
76147614 rl: ResultLoc,
7615 node: ast.Node.Index,
7616 lhs_node: ast.Node.Index,
7617 rhs_node: ast.Node.Index,
7615 node: Ast.Node.Index,
7616 lhs_node: Ast.Node.Index,
7617 rhs_node: Ast.Node.Index,
76187618 tag: Zir.Inst.Tag,
76197619) InnerError!Zir.Inst.Ref {
76207620 const type_inst = try typeExpr(gz, scope, lhs_node);
......@@ -7630,9 +7630,9 @@ fn shiftOp(
76307630 gz: *GenZir,
76317631 scope: *Scope,
76327632 rl: ResultLoc,
7633 node: ast.Node.Index,
7634 lhs_node: ast.Node.Index,
7635 rhs_node: ast.Node.Index,
7633 node: Ast.Node.Index,
7634 lhs_node: Ast.Node.Index,
7635 rhs_node: Ast.Node.Index,
76367636 tag: Zir.Inst.Tag,
76377637) InnerError!Zir.Inst.Ref {
76387638 const lhs = try expr(gz, scope, .none, lhs_node);
......@@ -7649,8 +7649,8 @@ fn cImport(
76497649 gz: *GenZir,
76507650 scope: *Scope,
76517651 rl: ResultLoc,
7652 node: ast.Node.Index,
7653 body_node: ast.Node.Index,
7652 node: Ast.Node.Index,
7653 body_node: Ast.Node.Index,
76547654) InnerError!Zir.Inst.Ref {
76557655 const astgen = gz.astgen;
76567656 const gpa = astgen.gpa;
......@@ -7674,8 +7674,8 @@ fn overflowArithmetic(
76747674 gz: *GenZir,
76757675 scope: *Scope,
76767676 rl: ResultLoc,
7677 node: ast.Node.Index,
7678 params: []const ast.Node.Index,
7677 node: Ast.Node.Index,
7678 params: []const Ast.Node.Index,
76797679 tag: Zir.Inst.Extended,
76807680) InnerError!Zir.Inst.Ref {
76817681 const int_type = try typeExpr(gz, scope, params[0]);
......@@ -7722,8 +7722,8 @@ fn callExpr(
77227722 gz: *GenZir,
77237723 scope: *Scope,
77247724 rl: ResultLoc,
7725 node: ast.Node.Index,
7726 call: ast.full.Call,
7725 node: Ast.Node.Index,
7726 call: Ast.full.Call,
77277727) InnerError!Zir.Inst.Ref {
77287728 const astgen = gz.astgen;
77297729 const lhs = try expr(gz, scope, .none, call.ast.fn_expr);
......@@ -7812,7 +7812,7 @@ pub const simple_types = std.ComptimeStringMap(Zir.Inst.Ref, .{
78127812 .{ "void", .void_type },
78137813});
78147814
7815fn nodeMayNeedMemoryLocation(tree: *const ast.Tree, start_node: ast.Node.Index) bool {
7815fn nodeMayNeedMemoryLocation(tree: *const Ast, start_node: Ast.Node.Index) bool {
78167816 const node_tags = tree.nodes.items(.tag);
78177817 const node_datas = tree.nodes.items(.data);
78187818 const main_tokens = tree.nodes.items(.main_token);
......@@ -8021,7 +8021,7 @@ fn nodeMayNeedMemoryLocation(tree: *const ast.Tree, start_node: ast.Node.Index)
80218021 }
80228022}
80238023
8024fn nodeMayEvalToError(tree: *const ast.Tree, start_node: ast.Node.Index) enum { never, always, maybe } {
8024fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) enum { never, always, maybe } {
80258025 const node_tags = tree.nodes.items(.tag);
80268026 const node_datas = tree.nodes.items(.data);
80278027 const main_tokens = tree.nodes.items(.main_token);
......@@ -8230,7 +8230,7 @@ fn nodeMayEvalToError(tree: *const ast.Tree, start_node: ast.Node.Index) enum {
82308230 }
82318231}
82328232
8233fn nodeImpliesRuntimeBits(tree: *const ast.Tree, start_node: ast.Node.Index) bool {
8233fn nodeImpliesRuntimeBits(tree: *const Ast, start_node: Ast.Node.Index) bool {
82348234 const node_tags = tree.nodes.items(.tag);
82358235 const node_datas = tree.nodes.items(.data);
82368236
......@@ -8417,7 +8417,7 @@ fn rvalue(
84178417 gz: *GenZir,
84188418 rl: ResultLoc,
84198419 result: Zir.Inst.Ref,
8420 src_node: ast.Node.Index,
8420 src_node: Ast.Node.Index,
84218421) InnerError!Zir.Inst.Ref {
84228422 if (gz.endsWithNoReturn()) return result;
84238423 switch (rl) {
......@@ -8522,7 +8522,7 @@ fn rvalue(
85228522/// and allocates the result within `astgen.arena`.
85238523/// Otherwise, returns a reference to the source code bytes directly.
85248524/// See also `appendIdentStr` and `parseStrLit`.
8525fn identifierTokenString(astgen: *AstGen, token: ast.TokenIndex) InnerError![]const u8 {
8525fn identifierTokenString(astgen: *AstGen, token: Ast.TokenIndex) InnerError![]const u8 {
85268526 const tree = astgen.tree;
85278527 const token_tags = tree.tokens.items(.tag);
85288528 assert(token_tags[token] == .identifier);
......@@ -8542,7 +8542,7 @@ fn identifierTokenString(astgen: *AstGen, token: ast.TokenIndex) InnerError![]co
85428542/// See also `identifierTokenString` and `parseStrLit`.
85438543fn appendIdentStr(
85448544 astgen: *AstGen,
8545 token: ast.TokenIndex,
8545 token: Ast.TokenIndex,
85468546 buf: *ArrayListUnmanaged(u8),
85478547) InnerError!void {
85488548 const tree = astgen.tree;
......@@ -8559,7 +8559,7 @@ fn appendIdentStr(
85598559/// Appends the result to `buf`.
85608560fn parseStrLit(
85618561 astgen: *AstGen,
8562 token: ast.TokenIndex,
8562 token: Ast.TokenIndex,
85638563 buf: *ArrayListUnmanaged(u8),
85648564 bytes: []const u8,
85658565 offset: u32,
......@@ -8623,7 +8623,7 @@ fn parseStrLit(
86238623
86248624fn failNode(
86258625 astgen: *AstGen,
8626 node: ast.Node.Index,
8626 node: Ast.Node.Index,
86278627 comptime format: []const u8,
86288628 args: anytype,
86298629) InnerError {
......@@ -8632,7 +8632,7 @@ fn failNode(
86328632
86338633fn failNodeNotes(
86348634 astgen: *AstGen,
8635 node: ast.Node.Index,
8635 node: Ast.Node.Index,
86368636 comptime format: []const u8,
86378637 args: anytype,
86388638 notes: []const u32,
......@@ -8664,7 +8664,7 @@ fn failNodeNotes(
86648664
86658665fn failTok(
86668666 astgen: *AstGen,
8667 token: ast.TokenIndex,
8667 token: Ast.TokenIndex,
86688668 comptime format: []const u8,
86698669 args: anytype,
86708670) InnerError {
......@@ -8673,7 +8673,7 @@ fn failTok(
86738673
86748674fn failTokNotes(
86758675 astgen: *AstGen,
8676 token: ast.TokenIndex,
8676 token: Ast.TokenIndex,
86778677 comptime format: []const u8,
86788678 args: anytype,
86798679 notes: []const u32,
......@@ -8706,7 +8706,7 @@ fn failTokNotes(
87068706/// Same as `fail`, except given an absolute byte offset.
87078707fn failOff(
87088708 astgen: *AstGen,
8709 token: ast.TokenIndex,
8709 token: Ast.TokenIndex,
87108710 byte_offset: u32,
87118711 comptime format: []const u8,
87128712 args: anytype,
......@@ -8731,7 +8731,7 @@ fn failOff(
87318731
87328732fn errNoteTok(
87338733 astgen: *AstGen,
8734 token: ast.TokenIndex,
8734 token: Ast.TokenIndex,
87358735 comptime format: []const u8,
87368736 args: anytype,
87378737) Allocator.Error!u32 {
......@@ -8754,7 +8754,7 @@ fn errNoteTok(
87548754
87558755fn errNoteNode(
87568756 astgen: *AstGen,
8757 node: ast.Node.Index,
8757 node: Ast.Node.Index,
87588758 comptime format: []const u8,
87598759 args: anytype,
87608760) Allocator.Error!u32 {
......@@ -8775,7 +8775,7 @@ fn errNoteNode(
87758775 });
87768776}
87778777
8778fn identAsString(astgen: *AstGen, ident_token: ast.TokenIndex) !u32 {
8778fn identAsString(astgen: *AstGen, ident_token: Ast.TokenIndex) !u32 {
87798779 const gpa = astgen.gpa;
87808780 const string_bytes = &astgen.string_bytes;
87818781 const str_index = @intCast(u32, string_bytes.items.len);
......@@ -8798,7 +8798,7 @@ fn identAsString(astgen: *AstGen, ident_token: ast.TokenIndex) !u32 {
87988798
87998799const IndexSlice = struct { index: u32, len: u32 };
88008800
8801fn strLitAsString(astgen: *AstGen, str_lit_token: ast.TokenIndex) !IndexSlice {
8801fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice {
88028802 const gpa = astgen.gpa;
88038803 const string_bytes = &astgen.string_bytes;
88048804 const str_index = @intCast(u32, string_bytes.items.len);
......@@ -8829,7 +8829,7 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: ast.TokenIndex) !IndexSlice {
88298829 }
88308830}
88318831
8832fn strLitNodeAsString(astgen: *AstGen, node: ast.Node.Index) !IndexSlice {
8832fn strLitNodeAsString(astgen: *AstGen, node: Ast.Node.Index) !IndexSlice {
88338833 const tree = astgen.tree;
88348834 const node_datas = tree.nodes.items(.data);
88358835
......@@ -8864,7 +8864,7 @@ fn strLitNodeAsString(astgen: *AstGen, node: ast.Node.Index) !IndexSlice {
88648864 };
88658865}
88668866
8867fn testNameString(astgen: *AstGen, str_lit_token: ast.TokenIndex) !u32 {
8867fn testNameString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !u32 {
88688868 const gpa = astgen.gpa;
88698869 const string_bytes = &astgen.string_bytes;
88708870 const str_index = @intCast(u32, string_bytes.items.len);
......@@ -8921,7 +8921,7 @@ const Scope = struct {
89218921 gen_zir: *GenZir,
89228922 inst: Zir.Inst.Ref,
89238923 /// Source location of the corresponding variable declaration.
8924 token_src: ast.TokenIndex,
8924 token_src: Ast.TokenIndex,
89258925 /// String table index.
89268926 name: u32,
89278927 id_cat: IdCat,
......@@ -8940,7 +8940,7 @@ const Scope = struct {
89408940 gen_zir: *GenZir,
89418941 ptr: Zir.Inst.Ref,
89428942 /// Source location of the corresponding variable declaration.
8943 token_src: ast.TokenIndex,
8943 token_src: Ast.TokenIndex,
89448944 /// String table index.
89458945 name: u32,
89468946 id_cat: IdCat,
......@@ -8955,7 +8955,7 @@ const Scope = struct {
89558955 base: Scope,
89568956 /// Parents can be: `LocalVal`, `LocalPtr`, `GenZir`, `Defer`.
89578957 parent: *Scope,
8958 defer_node: ast.Node.Index,
8958 defer_node: Ast.Node.Index,
89598959 };
89608960
89618961 /// Represents a global scope that has any number of declarations in it.
......@@ -8967,8 +8967,8 @@ const Scope = struct {
89678967 parent: *Scope,
89688968 /// Maps string table index to the source location of declaration,
89698969 /// for the purposes of reporting name shadowing compile errors.
8970 decls: std.AutoHashMapUnmanaged(u32, ast.Node.Index) = .{},
8971 node: ast.Node.Index,
8970 decls: std.AutoHashMapUnmanaged(u32, Ast.Node.Index) = .{},
8971 node: Ast.Node.Index,
89728972 };
89738973
89748974 const Top = struct {
......@@ -8987,7 +8987,7 @@ const GenZir = struct {
89878987 /// How decls created in this scope should be named.
89888988 anon_name_strategy: Zir.Inst.NameStrategy = .anon,
89898989 /// The containing decl AST node.
8990 decl_node_index: ast.Node.Index,
8990 decl_node_index: Ast.Node.Index,
89918991 /// The containing decl line index, absolute.
89928992 decl_line: u32,
89938993 parent: *Scope,
......@@ -9022,8 +9022,8 @@ const GenZir = struct {
90229022 /// a result location pointer.
90239023 labeled_store_to_block_ptr_list: ArrayListUnmanaged(Zir.Inst.Index) = .{},
90249024
9025 suspend_node: ast.Node.Index = 0,
9026 nosuspend_node: ast.Node.Index = 0,
9025 suspend_node: Ast.Node.Index = 0,
9026 nosuspend_node: Ast.Node.Index = 0,
90279027
90289028 fn makeSubBlock(gz: *GenZir, scope: *Scope) GenZir {
90299029 return .{
......@@ -9039,7 +9039,7 @@ const GenZir = struct {
90399039 }
90409040
90419041 const Label = struct {
9042 token: ast.TokenIndex,
9042 token: Ast.TokenIndex,
90439043 block_inst: Zir.Inst.Index,
90449044 used: bool = false,
90459045 };
......@@ -9060,7 +9060,7 @@ const GenZir = struct {
90609060 return false;
90619061 }
90629062
9063 fn calcLine(gz: GenZir, node: ast.Node.Index) u32 {
9063 fn calcLine(gz: GenZir, node: Ast.Node.Index) u32 {
90649064 const astgen = gz.astgen;
90659065 const tree = astgen.tree;
90669066 const source = tree.source;
......@@ -9072,15 +9072,15 @@ const GenZir = struct {
90729072 return @intCast(u32, gz.decl_line + astgen.source_line);
90739073 }
90749074
9075 fn nodeIndexToRelative(gz: GenZir, node_index: ast.Node.Index) i32 {
9075 fn nodeIndexToRelative(gz: GenZir, node_index: Ast.Node.Index) i32 {
90769076 return @bitCast(i32, node_index) - @bitCast(i32, gz.decl_node_index);
90779077 }
90789078
9079 fn tokenIndexToRelative(gz: GenZir, token: ast.TokenIndex) u32 {
9079 fn tokenIndexToRelative(gz: GenZir, token: Ast.TokenIndex) u32 {
90809080 return token - gz.srcToken();
90819081 }
90829082
9083 fn srcToken(gz: GenZir) ast.TokenIndex {
9083 fn srcToken(gz: GenZir) Ast.TokenIndex {
90849084 return gz.astgen.tree.firstToken(gz.decl_node_index);
90859085 }
90869086
......@@ -9165,7 +9165,7 @@ const GenZir = struct {
91659165 }
91669166
91679167 fn addFunc(gz: *GenZir, args: struct {
9168 src_node: ast.Node.Index,
9168 src_node: Ast.Node.Index,
91699169 body: []const Zir.Inst.Index,
91709170 param_block: Zir.Inst.Index,
91719171 ret_ty: []const Zir.Inst.Index,
......@@ -9358,7 +9358,7 @@ const GenZir = struct {
93589358 callee: Zir.Inst.Ref,
93599359 args: []const Zir.Inst.Ref,
93609360 /// Absolute node index. This function does the conversion to offset from Decl.
9361 src_node: ast.Node.Index,
9361 src_node: Ast.Node.Index,
93629362 ) !Zir.Inst.Ref {
93639363 assert(callee != .none);
93649364 assert(src_node != 0);
......@@ -9449,7 +9449,7 @@ const GenZir = struct {
94499449 tag: Zir.Inst.Tag,
94509450 operand: Zir.Inst.Ref,
94519451 /// Absolute node index. This function does the conversion to offset from Decl.
9452 src_node: ast.Node.Index,
9452 src_node: Ast.Node.Index,
94539453 ) !Zir.Inst.Ref {
94549454 assert(operand != .none);
94559455 return gz.add(.{
......@@ -9465,7 +9465,7 @@ const GenZir = struct {
94659465 gz: *GenZir,
94669466 tag: Zir.Inst.Tag,
94679467 /// Absolute node index. This function does the conversion to offset from Decl.
9468 src_node: ast.Node.Index,
9468 src_node: Ast.Node.Index,
94699469 extra: anytype,
94709470 ) !Zir.Inst.Ref {
94719471 const gpa = gz.astgen.gpa;
......@@ -9489,7 +9489,7 @@ const GenZir = struct {
94899489 gz: *GenZir,
94909490 tag: Zir.Inst.Tag,
94919491 /// Absolute token index. This function does the conversion to Decl offset.
9492 abs_tok_index: ast.TokenIndex,
9492 abs_tok_index: Ast.TokenIndex,
94939493 name: u32,
94949494 body: []const u32,
94959495 ) !Zir.Inst.Index {
......@@ -9544,7 +9544,7 @@ const GenZir = struct {
95449544 fn addExtendedMultiOp(
95459545 gz: *GenZir,
95469546 opcode: Zir.Inst.Extended,
9547 node: ast.Node.Index,
9547 node: Ast.Node.Index,
95489548 operands: []const Zir.Inst.Ref,
95499549 ) !Zir.Inst.Ref {
95509550 const astgen = gz.astgen;
......@@ -9605,7 +9605,7 @@ const GenZir = struct {
96059605 tag: Zir.Inst.Tag,
96069606 operand: Zir.Inst.Ref,
96079607 /// Absolute token index. This function does the conversion to Decl offset.
9608 abs_tok_index: ast.TokenIndex,
9608 abs_tok_index: Ast.TokenIndex,
96099609 ) !Zir.Inst.Ref {
96109610 assert(operand != .none);
96119611 return gz.add(.{
......@@ -9622,7 +9622,7 @@ const GenZir = struct {
96229622 tag: Zir.Inst.Tag,
96239623 str_index: u32,
96249624 /// Absolute token index. This function does the conversion to Decl offset.
9625 abs_tok_index: ast.TokenIndex,
9625 abs_tok_index: Ast.TokenIndex,
96269626 ) !Zir.Inst.Ref {
96279627 return gz.add(.{
96289628 .tag = tag,
......@@ -9669,7 +9669,7 @@ const GenZir = struct {
96699669 gz: *GenZir,
96709670 tag: Zir.Inst.Tag,
96719671 decl_index: u32,
9672 src_node: ast.Node.Index,
9672 src_node: Ast.Node.Index,
96739673 ) !Zir.Inst.Ref {
96749674 return gz.add(.{
96759675 .tag = tag,
......@@ -9684,7 +9684,7 @@ const GenZir = struct {
96849684 gz: *GenZir,
96859685 tag: Zir.Inst.Tag,
96869686 /// Absolute node index. This function does the conversion to offset from Decl.
9687 src_node: ast.Node.Index,
9687 src_node: Ast.Node.Index,
96889688 ) !Zir.Inst.Ref {
96899689 return gz.add(.{
96909690 .tag = tag,
......@@ -9696,7 +9696,7 @@ const GenZir = struct {
96969696 gz: *GenZir,
96979697 opcode: Zir.Inst.Extended,
96989698 /// Absolute node index. This function does the conversion to offset from Decl.
9699 src_node: ast.Node.Index,
9699 src_node: Ast.Node.Index,
97009700 ) !Zir.Inst.Ref {
97019701 return gz.add(.{
97029702 .tag = .extended,
......@@ -9712,7 +9712,7 @@ const GenZir = struct {
97129712 gz: *GenZir,
97139713 args: struct {
97149714 /// Absolute node index. This function does the conversion to offset from Decl.
9715 node: ast.Node.Index,
9715 node: Ast.Node.Index,
97169716 type_inst: Zir.Inst.Ref,
97179717 align_inst: Zir.Inst.Ref,
97189718 is_const: bool,
......@@ -9763,7 +9763,7 @@ const GenZir = struct {
97639763 gz: *GenZir,
97649764 args: struct {
97659765 /// Absolute node index. This function does the conversion to offset from Decl.
9766 node: ast.Node.Index,
9766 node: Ast.Node.Index,
97679767 asm_source: u32,
97689768 output_type_bits: u32,
97699769 is_volatile: bool,
......@@ -9820,7 +9820,7 @@ const GenZir = struct {
98209820 /// Note that this returns a `Zir.Inst.Index` not a ref.
98219821 /// Does *not* append the block instruction to the scope.
98229822 /// Leaves the `payload_index` field undefined.
9823 fn addBlock(gz: *GenZir, tag: Zir.Inst.Tag, node: ast.Node.Index) !Zir.Inst.Index {
9823 fn addBlock(gz: *GenZir, tag: Zir.Inst.Tag, node: Ast.Node.Index) !Zir.Inst.Index {
98249824 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
98259825 const gpa = gz.astgen.gpa;
98269826 try gz.astgen.instructions.append(gpa, .{
......@@ -9835,7 +9835,7 @@ const GenZir = struct {
98359835
98369836 /// Note that this returns a `Zir.Inst.Index` not a ref.
98379837 /// Leaves the `payload_index` field undefined.
9838 fn addCondBr(gz: *GenZir, tag: Zir.Inst.Tag, node: ast.Node.Index) !Zir.Inst.Index {
9838 fn addCondBr(gz: *GenZir, tag: Zir.Inst.Tag, node: Ast.Node.Index) !Zir.Inst.Index {
98399839 const gpa = gz.astgen.gpa;
98409840 try gz.instructions.ensureUnusedCapacity(gpa, 1);
98419841 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
......@@ -9851,7 +9851,7 @@ const GenZir = struct {
98519851 }
98529852
98539853 fn setStruct(gz: *GenZir, inst: Zir.Inst.Index, args: struct {
9854 src_node: ast.Node.Index,
9854 src_node: Ast.Node.Index,
98559855 body_len: u32,
98569856 fields_len: u32,
98579857 decls_len: u32,
......@@ -9896,7 +9896,7 @@ const GenZir = struct {
98969896 }
98979897
98989898 fn setUnion(gz: *GenZir, inst: Zir.Inst.Index, args: struct {
9899 src_node: ast.Node.Index,
9899 src_node: Ast.Node.Index,
99009900 tag_type: Zir.Inst.Ref,
99019901 body_len: u32,
99029902 fields_len: u32,
......@@ -9946,7 +9946,7 @@ const GenZir = struct {
99469946 }
99479947
99489948 fn setEnum(gz: *GenZir, inst: Zir.Inst.Index, args: struct {
9949 src_node: ast.Node.Index,
9949 src_node: Ast.Node.Index,
99509950 tag_type: Zir.Inst.Ref,
99519951 body_len: u32,
99529952 fields_len: u32,
......@@ -10019,7 +10019,7 @@ const GenZir = struct {
1001910019 return new_index;
1002010020 }
1002110021
10022 fn addRet(gz: *GenZir, rl: ResultLoc, operand: Zir.Inst.Ref, node: ast.Node.Index) !void {
10022 fn addRet(gz: *GenZir, rl: ResultLoc, operand: Zir.Inst.Ref, node: Ast.Node.Index) !void {
1002310023 switch (rl) {
1002410024 .ptr => |ret_ptr| _ = try gz.addUnNode(.ret_load, ret_ptr, node),
1002510025 .ty => _ = try gz.addUnNode(.ret_node, operand, node),
......@@ -10052,7 +10052,7 @@ fn detectLocalShadowing(
1005210052 astgen: *AstGen,
1005310053 scope: *Scope,
1005410054 ident_name: u32,
10055 name_token: ast.TokenIndex,
10055 name_token: Ast.TokenIndex,
1005610056 token_bytes: []const u8,
1005710057) !void {
1005810058 const gpa = astgen.gpa;
......@@ -10157,7 +10157,7 @@ fn refToIndex(inst: Zir.Inst.Ref) ?Zir.Inst.Index {
1015710157 }
1015810158}
1015910159
10160fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const ast.Node.Index) !void {
10160fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast.Node.Index) !void {
1016110161 const gpa = astgen.gpa;
1016210162 const tree = astgen.tree;
1016310163 const node_tags = tree.nodes.items(.tag);
src/Compilation.zig+1-1
......@@ -2408,7 +2408,7 @@ const AstGenSrc = union(enum) {
24082408 root,
24092409 import: struct {
24102410 importing_file: *Module.Scope.File,
2411 import_tok: std.zig.ast.TokenIndex,
2411 import_tok: std.zig.Ast.TokenIndex,
24122412 },
24132413};
24142414
src/Module.zig+24-24
......@@ -11,7 +11,7 @@ const log = std.log.scoped(.module);
1111const BigIntConst = std.math.big.int.Const;
1212const BigIntMutable = std.math.big.int.Mutable;
1313const Target = std.Target;
14const ast = std.zig.ast;
14const Ast = std.zig.Ast;
1515
1616const Module = @This();
1717const Compilation = @import("Compilation.zig");
......@@ -291,7 +291,7 @@ pub const Decl = struct {
291291 generation: u32,
292292 /// The AST node index of this declaration.
293293 /// Must be recomputed when the corresponding source file is modified.
294 src_node: ast.Node.Index,
294 src_node: Ast.Node.Index,
295295 /// Line number corresponding to `src_node`. Stored separately so that source files
296296 /// do not need to be loaded into memory in order to compute debug line numbers.
297297 src_line: u32,
......@@ -499,19 +499,19 @@ pub const Decl = struct {
499499 return decl.src_line + offset;
500500 }
501501
502 pub fn relativeToNodeIndex(decl: Decl, offset: i32) ast.Node.Index {
503 return @bitCast(ast.Node.Index, offset + @bitCast(i32, decl.src_node));
502 pub fn relativeToNodeIndex(decl: Decl, offset: i32) Ast.Node.Index {
503 return @bitCast(Ast.Node.Index, offset + @bitCast(i32, decl.src_node));
504504 }
505505
506 pub fn nodeIndexToRelative(decl: Decl, node_index: ast.Node.Index) i32 {
506 pub fn nodeIndexToRelative(decl: Decl, node_index: Ast.Node.Index) i32 {
507507 return @bitCast(i32, node_index) - @bitCast(i32, decl.src_node);
508508 }
509509
510 pub fn tokSrcLoc(decl: Decl, token_index: ast.TokenIndex) LazySrcLoc {
510 pub fn tokSrcLoc(decl: Decl, token_index: Ast.TokenIndex) LazySrcLoc {
511511 return .{ .token_offset = token_index - decl.srcToken() };
512512 }
513513
514 pub fn nodeSrcLoc(decl: Decl, node_index: ast.Node.Index) LazySrcLoc {
514 pub fn nodeSrcLoc(decl: Decl, node_index: Ast.Node.Index) LazySrcLoc {
515515 return .{ .node_offset = decl.nodeIndexToRelative(node_index) };
516516 }
517517
......@@ -527,7 +527,7 @@ pub const Decl = struct {
527527 };
528528 }
529529
530 pub fn srcToken(decl: Decl) ast.TokenIndex {
530 pub fn srcToken(decl: Decl) Ast.TokenIndex {
531531 const tree = &decl.namespace.file_scope.tree;
532532 return tree.firstToken(decl.src_node);
533533 }
......@@ -1121,7 +1121,7 @@ pub const Scope = struct {
11211121 /// Whether this is populated depends on `status`.
11221122 stat_mtime: i128,
11231123 /// Whether this is populated or not depends on `tree_loaded`.
1124 tree: ast.Tree,
1124 tree: Ast,
11251125 /// Whether this is populated or not depends on `zir_loaded`.
11261126 zir: Zir,
11271127 /// Package that this file is a part of, managed externally.
......@@ -1220,7 +1220,7 @@ pub const Scope = struct {
12201220 return source;
12211221 }
12221222
1223 pub fn getTree(file: *File, gpa: *Allocator) !*const ast.Tree {
1223 pub fn getTree(file: *File, gpa: *Allocator) !*const Ast {
12241224 if (file.tree_loaded) return &file.tree;
12251225
12261226 const source = try file.getSource(gpa);
......@@ -1565,17 +1565,17 @@ pub const ErrorMsg = struct {
15651565pub const SrcLoc = struct {
15661566 file_scope: *Scope.File,
15671567 /// Might be 0 depending on tag of `lazy`.
1568 parent_decl_node: ast.Node.Index,
1568 parent_decl_node: Ast.Node.Index,
15691569 /// Relative to `parent_decl_node`.
15701570 lazy: LazySrcLoc,
15711571
1572 pub fn declSrcToken(src_loc: SrcLoc) ast.TokenIndex {
1572 pub fn declSrcToken(src_loc: SrcLoc) Ast.TokenIndex {
15731573 const tree = src_loc.file_scope.tree;
15741574 return tree.firstToken(src_loc.parent_decl_node);
15751575 }
15761576
1577 pub fn declRelativeToNodeIndex(src_loc: SrcLoc, offset: i32) ast.TokenIndex {
1578 return @bitCast(ast.Node.Index, offset + @bitCast(i32, src_loc.parent_decl_node));
1577 pub fn declRelativeToNodeIndex(src_loc: SrcLoc, offset: i32) Ast.TokenIndex {
1578 return @bitCast(Ast.Node.Index, offset + @bitCast(i32, src_loc.parent_decl_node));
15791579 }
15801580
15811581 pub fn byteOffset(src_loc: SrcLoc, gpa: *Allocator) !u32 {
......@@ -1701,7 +1701,7 @@ pub const SrcLoc = struct {
17011701 const tree = try src_loc.file_scope.getTree(gpa);
17021702 const node_tags = tree.nodes.items(.tag);
17031703 const node = src_loc.declRelativeToNodeIndex(node_off);
1704 var params: [1]ast.Node.Index = undefined;
1704 var params: [1]Ast.Node.Index = undefined;
17051705 const full = switch (node_tags[node]) {
17061706 .call_one,
17071707 .call_one_comma,
......@@ -1831,7 +1831,7 @@ pub const SrcLoc = struct {
18311831 const node_datas = tree.nodes.items(.data);
18321832 const node_tags = tree.nodes.items(.tag);
18331833 const main_tokens = tree.nodes.items(.main_token);
1834 const extra = tree.extraData(node_datas[switch_node].rhs, ast.Node.SubRange);
1834 const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange);
18351835 const case_nodes = tree.extra_data[extra.start..extra.end];
18361836 for (case_nodes) |case_node| {
18371837 const case = switch (node_tags[case_node]) {
......@@ -1857,7 +1857,7 @@ pub const SrcLoc = struct {
18571857 const node_datas = tree.nodes.items(.data);
18581858 const node_tags = tree.nodes.items(.tag);
18591859 const main_tokens = tree.nodes.items(.main_token);
1860 const extra = tree.extraData(node_datas[switch_node].rhs, ast.Node.SubRange);
1860 const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange);
18611861 const case_nodes = tree.extra_data[extra.start..extra.end];
18621862 for (case_nodes) |case_node| {
18631863 const case = switch (node_tags[case_node]) {
......@@ -1886,7 +1886,7 @@ pub const SrcLoc = struct {
18861886 const node_datas = tree.nodes.items(.data);
18871887 const node_tags = tree.nodes.items(.tag);
18881888 const node = src_loc.declRelativeToNodeIndex(node_off);
1889 var params: [1]ast.Node.Index = undefined;
1889 var params: [1]Ast.Node.Index = undefined;
18901890 const full = switch (node_tags[node]) {
18911891 .fn_proto_simple => tree.fnProtoSimple(&params, node),
18921892 .fn_proto_multi => tree.fnProtoMulti(node),
......@@ -1911,7 +1911,7 @@ pub const SrcLoc = struct {
19111911 const tree = try src_loc.file_scope.getTree(gpa);
19121912 const node_tags = tree.nodes.items(.tag);
19131913 const node = src_loc.declRelativeToNodeIndex(node_off);
1914 var params: [1]ast.Node.Index = undefined;
1914 var params: [1]Ast.Node.Index = undefined;
19151915 const full = switch (node_tags[node]) {
19161916 .fn_proto_simple => tree.fnProtoSimple(&params, node),
19171917 .fn_proto_multi => tree.fnProtoMulti(node),
......@@ -1941,7 +1941,7 @@ pub const SrcLoc = struct {
19411941 const node_datas = tree.nodes.items(.data);
19421942 const node_tags = tree.nodes.items(.tag);
19431943 const parent_node = src_loc.declRelativeToNodeIndex(node_off);
1944 var params: [1]ast.Node.Index = undefined;
1944 var params: [1]Ast.Node.Index = undefined;
19451945 const full = switch (node_tags[parent_node]) {
19461946 .fn_proto_simple => tree.fnProtoSimple(&params, parent_node),
19471947 .fn_proto_multi => tree.fnProtoMulti(parent_node),
......@@ -3967,7 +3967,7 @@ fn markOutdatedDecl(mod: *Module, decl: *Decl) !void {
39673967 decl.analysis = .outdated;
39683968}
39693969
3970pub fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: ast.Node.Index) !*Decl {
3970pub fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: Ast.Node.Index) !*Decl {
39713971 // If we have emit-h then we must allocate a bigger structure to store the emit-h state.
39723972 const new_decl: *Decl = if (mod.emit_h != null) blk: {
39733973 const parent_struct = try mod.gpa.create(DeclPlusEmitH);
......@@ -4237,7 +4237,7 @@ pub fn fail(
42374237pub fn failTok(
42384238 mod: *Module,
42394239 scope: *Scope,
4240 token_index: ast.TokenIndex,
4240 token_index: Ast.TokenIndex,
42414241 comptime format: []const u8,
42424242 args: anytype,
42434243) CompileError {
......@@ -4250,7 +4250,7 @@ pub fn failTok(
42504250pub fn failNode(
42514251 mod: *Module,
42524252 scope: *Scope,
4253 node_index: ast.Node.Index,
4253 node_index: Ast.Node.Index,
42544254 comptime format: []const u8,
42554255 args: anytype,
42564256) CompileError {
......@@ -4455,7 +4455,7 @@ pub const SwitchProngSrc = union(enum) {
44554455 const main_tokens = tree.nodes.items(.main_token);
44564456 const node_datas = tree.nodes.items(.data);
44574457 const node_tags = tree.nodes.items(.tag);
4458 const extra = tree.extraData(node_datas[switch_node].rhs, ast.Node.SubRange);
4458 const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange);
44594459 const case_nodes = tree.extra_data[extra.start..extra.end];
44604460
44614461 var multi_i: u32 = 0;
src/Sema.zig+3-3
......@@ -10177,7 +10177,7 @@ fn typeHasOnePossibleValue(
1017710177 };
1017810178}
1017910179
10180fn getAstTree(sema: *Sema, block: *Scope.Block) CompileError!*const std.zig.ast.Tree {
10180fn getAstTree(sema: *Sema, block: *Scope.Block) CompileError!*const std.zig.Ast {
1018110181 return block.src_decl.namespace.file_scope.getTree(sema.gpa) catch |err| {
1018210182 log.err("unable to load AST to report compile error: {s}", .{@errorName(err)});
1018310183 return error.AnalysisFail;
......@@ -10186,14 +10186,14 @@ fn getAstTree(sema: *Sema, block: *Scope.Block) CompileError!*const std.zig.ast.
1018610186
1018710187fn enumFieldSrcLoc(
1018810188 decl: *Decl,
10189 tree: std.zig.ast.Tree,
10189 tree: std.zig.Ast,
1019010190 node_offset: i32,
1019110191 field_index: usize,
1019210192) LazySrcLoc {
1019310193 @setCold(true);
1019410194 const enum_node = decl.relativeToNodeIndex(node_offset);
1019510195 const node_tags = tree.nodes.items(.tag);
10196 var buffer: [2]std.zig.ast.Node.Index = undefined;
10196 var buffer: [2]std.zig.Ast.Node.Index = undefined;
1019710197 const container_decl = switch (node_tags[enum_node]) {
1019810198 .container_decl,
1019910199 .container_decl_trailing,
src/Zir.zig+9-9
......@@ -16,7 +16,7 @@ const Allocator = std.mem.Allocator;
1616const assert = std.debug.assert;
1717const BigIntConst = std.math.big.int.Const;
1818const BigIntMutable = std.math.big.int.Mutable;
19const ast = std.zig.ast;
19const Ast = std.zig.Ast;
2020
2121const Zir = @This();
2222const Type = @import("type.zig").Type;
......@@ -2092,7 +2092,7 @@ pub const Inst = struct {
20922092 /// Used for unary operators, with a token source location.
20932093 un_tok: struct {
20942094 /// Offset from Decl AST token index.
2095 src_tok: ast.TokenIndex,
2095 src_tok: Ast.TokenIndex,
20962096 /// The meaning of this operand depends on the corresponding `Tag`.
20972097 operand: Ref,
20982098
......@@ -2114,7 +2114,7 @@ pub const Inst = struct {
21142114 },
21152115 pl_tok: struct {
21162116 /// Offset from Decl AST token index.
2117 src_tok: ast.TokenIndex,
2117 src_tok: Ast.TokenIndex,
21182118 /// index into extra.
21192119 /// `Tag` determines what lives there.
21202120 payload_index: u32,
......@@ -2150,7 +2150,7 @@ pub const Inst = struct {
21502150 }
21512151 },
21522152 /// Offset from Decl AST token index.
2153 tok: ast.TokenIndex,
2153 tok: Ast.TokenIndex,
21542154 /// Offset from Decl AST node index.
21552155 node: i32,
21562156 int: u64,
......@@ -2878,9 +2878,9 @@ pub const Inst = struct {
28782878 pub const Item = struct {
28792879 /// null terminated string index
28802880 msg: u32,
2881 node: ast.Node.Index,
2881 node: Ast.Node.Index,
28822882 /// If node is 0 then this will be populated.
2883 token: ast.TokenIndex,
2883 token: Ast.TokenIndex,
28842884 /// Can be used in combination with `token`.
28852885 byte_offset: u32,
28862886 /// 0 or a payload index of a `Block`, each is a payload
......@@ -2897,7 +2897,7 @@ pub const Inst = struct {
28972897 /// null terminated string index
28982898 name: u32,
28992899 /// points to the import name
2900 token: ast.TokenIndex,
2900 token: Ast.TokenIndex,
29012901 };
29022902 };
29032903};
......@@ -2912,8 +2912,8 @@ const Writer = struct {
29122912 indent: u32,
29132913 parent_decl_node: u32,
29142914
2915 fn relativeToNodeIndex(self: *Writer, offset: i32) ast.Node.Index {
2916 return @bitCast(ast.Node.Index, offset + @bitCast(i32, self.parent_decl_node));
2915 fn relativeToNodeIndex(self: *Writer, offset: i32) Ast.Node.Index {
2916 return @bitCast(Ast.Node.Index, offset + @bitCast(i32, self.parent_decl_node));
29172917 }
29182918
29192919 fn writeInstToStream(
src/main.zig+9-9
......@@ -6,7 +6,7 @@ const mem = std.mem;
66const process = std.process;
77const Allocator = mem.Allocator;
88const ArrayList = std.ArrayList;
9const ast = std.zig.ast;
9const Ast = std.zig.Ast;
1010const warn = std.log.warn;
1111
1212const Compilation = @import("Compilation.zig");
......@@ -3423,8 +3423,8 @@ fn fmtPathFile(
34233423fn printErrMsgToStdErr(
34243424 gpa: *mem.Allocator,
34253425 arena: *mem.Allocator,
3426 parse_error: ast.Error,
3427 tree: ast.Tree,
3426 parse_error: Ast.Error,
3427 tree: Ast,
34283428 path: []const u8,
34293429 color: Color,
34303430) !void {
......@@ -4029,12 +4029,12 @@ pub fn cmdAstCheck(
40294029 }
40304030
40314031 {
4032 const token_bytes = @sizeOf(std.zig.ast.TokenList) +
4033 file.tree.tokens.len * (@sizeOf(std.zig.Token.Tag) + @sizeOf(std.zig.ast.ByteOffset));
4034 const tree_bytes = @sizeOf(std.zig.ast.Tree) + file.tree.nodes.len *
4035 (@sizeOf(std.zig.ast.Node.Tag) +
4036 @sizeOf(std.zig.ast.Node.Data) +
4037 @sizeOf(std.zig.ast.TokenIndex));
4032 const token_bytes = @sizeOf(Ast.TokenList) +
4033 file.tree.tokens.len * (@sizeOf(std.zig.Token.Tag) + @sizeOf(Ast.ByteOffset));
4034 const tree_bytes = @sizeOf(Ast) + file.tree.nodes.len *
4035 (@sizeOf(Ast.Node.Tag) +
4036 @sizeOf(Ast.Node.Data) +
4037 @sizeOf(Ast.TokenIndex));
40384038 const instruction_bytes = file.zir.instructions.len *
40394039 // Here we don't use @sizeOf(Zir.Inst.Data) because it would include
40404040 // the debug safety tag but we want to measure release size.
src/translate_c.zig+2-2
......@@ -356,7 +356,7 @@ pub fn translate(
356356 args_end: [*]?[*]const u8,
357357 errors: *[]ClangErrMsg,
358358 resources_path: [*:0]const u8,
359) !std.zig.ast.Tree {
359) !std.zig.Ast {
360360 const ast_unit = clang.LoadFromCommandLine(
361361 args_begin,
362362 args_end,
......@@ -369,7 +369,7 @@ pub fn translate(
369369 };
370370 defer ast_unit.delete();
371371
372 // For memory that has the same lifetime as the Tree that we return
372 // For memory that has the same lifetime as the Ast that we return
373373 // from this function.
374374 var arena = std.heap.ArenaAllocator.init(gpa);
375375 errdefer arena.deinit();
src/translate_c/ast.zig+22-22
......@@ -714,9 +714,9 @@ pub const Payload = struct {
714714 };
715715};
716716
717/// Converts the nodes into a Zig ast.
717/// Converts the nodes into a Zig Ast.
718718/// Caller must free the source slice.
719pub fn render(gpa: *Allocator, nodes: []const Node) !std.zig.ast.Tree {
719pub fn render(gpa: *Allocator, nodes: []const Node) !std.zig.Ast {
720720 var ctx = Context{
721721 .gpa = gpa,
722722 .buf = std.ArrayList(u8).init(gpa),
......@@ -767,7 +767,7 @@ pub fn render(gpa: *Allocator, nodes: []const Node) !std.zig.ast.Tree {
767767 .start = @intCast(u32, ctx.buf.items.len),
768768 });
769769
770 return std.zig.ast.Tree{
770 return std.zig.Ast{
771771 .source = try ctx.buf.toOwnedSliceSentinel(0),
772772 .tokens = ctx.tokens.toOwnedSlice(),
773773 .nodes = ctx.nodes.toOwnedSlice(),
......@@ -776,17 +776,17 @@ pub fn render(gpa: *Allocator, nodes: []const Node) !std.zig.ast.Tree {
776776 };
777777}
778778
779const NodeIndex = std.zig.ast.Node.Index;
780const NodeSubRange = std.zig.ast.Node.SubRange;
781const TokenIndex = std.zig.ast.TokenIndex;
779const NodeIndex = std.zig.Ast.Node.Index;
780const NodeSubRange = std.zig.Ast.Node.SubRange;
781const TokenIndex = std.zig.Ast.TokenIndex;
782782const TokenTag = std.zig.Token.Tag;
783783
784784const Context = struct {
785785 gpa: *Allocator,
786786 buf: std.ArrayList(u8) = .{},
787 nodes: std.zig.ast.NodeList = .{},
788 extra_data: std.ArrayListUnmanaged(std.zig.ast.Node.Index) = .{},
789 tokens: std.zig.ast.TokenList = .{},
787 nodes: std.zig.Ast.NodeList = .{},
788 extra_data: std.ArrayListUnmanaged(std.zig.Ast.Node.Index) = .{},
789 tokens: std.zig.Ast.TokenList = .{},
790790
791791 fn addTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex {
792792 const start_index = c.buf.items.len;
......@@ -831,7 +831,7 @@ const Context = struct {
831831 };
832832 }
833833
834 fn addNode(c: *Context, elem: std.zig.ast.NodeList.Elem) Allocator.Error!NodeIndex {
834 fn addNode(c: *Context, elem: std.zig.Ast.NodeList.Elem) Allocator.Error!NodeIndex {
835835 const result = @intCast(NodeIndex, c.nodes.len);
836836 try c.nodes.append(c.gpa, elem);
837837 return result;
......@@ -1166,7 +1166,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
11661166 .main_token = l_bracket,
11671167 .data = .{
11681168 .lhs = string,
1169 .rhs = try c.addExtra(std.zig.ast.Node.Slice{
1169 .rhs = try c.addExtra(std.zig.Ast.Node.Slice{
11701170 .start = start,
11711171 .end = end,
11721172 }),
......@@ -1601,7 +1601,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
16011601 .main_token = while_tok,
16021602 .data = .{
16031603 .lhs = cond,
1604 .rhs = try c.addExtra(std.zig.ast.Node.WhileCont{
1604 .rhs = try c.addExtra(std.zig.Ast.Node.WhileCont{
16051605 .cont_expr = cont_expr,
16061606 .then_expr = body,
16071607 }),
......@@ -1654,7 +1654,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
16541654 .main_token = if_tok,
16551655 .data = .{
16561656 .lhs = cond,
1657 .rhs = try c.addExtra(std.zig.ast.Node.If{
1657 .rhs = try c.addExtra(std.zig.Ast.Node.If{
16581658 .then_expr = then_expr,
16591659 .else_expr = else_expr,
16601660 }),
......@@ -2175,7 +2175,7 @@ fn renderNullSentinelArrayType(c: *Context, len: usize, elem_type: Node) !NodeIn
21752175 .main_token = l_bracket,
21762176 .data = .{
21772177 .lhs = len_expr,
2178 .rhs = try c.addExtra(std.zig.ast.Node.ArrayTypeSentinel{
2178 .rhs = try c.addExtra(std.zig.Ast.Node.ArrayTypeSentinel{
21792179 .sentinel = sentinel_expr,
21802180 .elem_type = elem_type_expr,
21812181 }),
......@@ -2378,7 +2378,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
23782378 }
23792379}
23802380
2381fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
2381fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
23822382 const payload = @fieldParentPtr(Payload.UnOp, "base", node.ptr_otherwise).data;
23832383 return c.addNode(.{
23842384 .tag = tag,
......@@ -2390,7 +2390,7 @@ fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: T
23902390 });
23912391}
23922392
2393fn renderBinOpGrouped(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
2393fn renderBinOpGrouped(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
23942394 const payload = @fieldParentPtr(Payload.BinOp, "base", node.ptr_otherwise).data;
23952395 const lhs = try renderNodeGrouped(c, payload.lhs);
23962396 return c.addNode(.{
......@@ -2403,7 +2403,7 @@ fn renderBinOpGrouped(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_ta
24032403 });
24042404}
24052405
2406fn renderBinOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
2406fn renderBinOp(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
24072407 const payload = @fieldParentPtr(Payload.BinOp, "base", node.ptr_otherwise).data;
24082408 const lhs = try renderNode(c, payload.lhs);
24092409 return c.addNode(.{
......@@ -2604,7 +2604,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex {
26042604 .tag = .local_var_decl,
26052605 .main_token = mut_tok,
26062606 .data = .{
2607 .lhs = try c.addExtra(std.zig.ast.Node.LocalVarDecl{
2607 .lhs = try c.addExtra(std.zig.Ast.Node.LocalVarDecl{
26082608 .type_node = type_node,
26092609 .align_node = align_node,
26102610 }),
......@@ -2617,7 +2617,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex {
26172617 .tag = .global_var_decl,
26182618 .main_token = mut_tok,
26192619 .data = .{
2620 .lhs = try c.addExtra(std.zig.ast.Node.GlobalVarDecl{
2620 .lhs = try c.addExtra(std.zig.Ast.Node.GlobalVarDecl{
26212621 .type_node = type_node,
26222622 .align_node = align_node,
26232623 .section_node = section_node,
......@@ -2709,7 +2709,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
27092709 .tag = .fn_proto_one,
27102710 .main_token = fn_token,
27112711 .data = .{
2712 .lhs = try c.addExtra(std.zig.ast.Node.FnProtoOne{
2712 .lhs = try c.addExtra(std.zig.Ast.Node.FnProtoOne{
27132713 .param = params.items[0],
27142714 .align_expr = align_expr,
27152715 .section_expr = section_expr,
......@@ -2723,7 +2723,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
27232723 .tag = .fn_proto,
27242724 .main_token = fn_token,
27252725 .data = .{
2726 .lhs = try c.addExtra(std.zig.ast.Node.FnProto{
2726 .lhs = try c.addExtra(std.zig.Ast.Node.FnProto{
27272727 .params_start = span.start,
27282728 .params_end = span.end,
27292729 .align_expr = align_expr,
......@@ -2781,7 +2781,7 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {
27812781 .tag = .fn_proto_multi,
27822782 .main_token = fn_token,
27832783 .data = .{
2784 .lhs = try c.addExtra(std.zig.ast.Node.SubRange{
2784 .lhs = try c.addExtra(std.zig.Ast.Node.SubRange{
27852785 .start = span.start,
27862786 .end = span.end,
27872787 }),