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...@@ -529,7 +529,7 @@ set(ZIG_STAGE2_SOURCES
529 "${CMAKE_SOURCE_DIR}/lib/std/time.zig"529 "${CMAKE_SOURCE_DIR}/lib/std/time.zig"
530 "${CMAKE_SOURCE_DIR}/lib/std/unicode.zig"530 "${CMAKE_SOURCE_DIR}/lib/std/unicode.zig"
531 "${CMAKE_SOURCE_DIR}/lib/std/zig.zig"531 "${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"
533 "${CMAKE_SOURCE_DIR}/lib/std/zig/cross_target.zig"533 "${CMAKE_SOURCE_DIR}/lib/std/zig/cross_target.zig"
534 "${CMAKE_SOURCE_DIR}/lib/std/zig/parse.zig"534 "${CMAKE_SOURCE_DIR}/lib/std/zig/parse.zig"
535 "${CMAKE_SOURCE_DIR}/lib/std/zig/render.zig"535 "${CMAKE_SOURCE_DIR}/lib/std/zig/render.zig"
lib/std/zig.zig+1-1
...@@ -10,7 +10,7 @@ pub const fmtEscapes = fmt.fmtEscapes;...@@ -10,7 +10,7 @@ pub const fmtEscapes = fmt.fmtEscapes;
10pub const isValidId = fmt.isValidId;10pub const isValidId = fmt.isValidId;
11pub const parse = @import("zig/parse.zig").parse;11pub const parse = @import("zig/parse.zig").parse;
12pub const string_literal = @import("zig/string_literal.zig");12pub const string_literal = @import("zig/string_literal.zig");
13pub const ast = @import("zig/ast.zig");13pub const Ast = @import("zig/Ast.zig");
14pub const system = @import("zig/system.zig");14pub const system = @import("zig/system.zig");
15pub const CrossTarget = @import("zig/cross_target.zig").CrossTarget;15pub 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 @@...@@ -1,19 +1,18 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const assert = std.debug.assert;2const assert = std.debug.assert;
3const Allocator = std.mem.Allocator;3const Allocator = std.mem.Allocator;
4const ast = std.zig.ast;4const Ast = std.zig.Ast;
5const Node = ast.Node;5const Node = Ast.Node;
6const Tree = ast.Tree;6const AstError = Ast.Error;
7const AstError = ast.Error;7const TokenIndex = Ast.TokenIndex;
8const TokenIndex = ast.TokenIndex;
9const Token = std.zig.Token;8const Token = std.zig.Token;
109
11pub const Error = error{ParseError} || Allocator.Error;10pub const Error = error{ParseError} || Allocator.Error;
1211
13/// Result should be freed with tree.deinit() when there are12/// Result should be freed with tree.deinit() when there are
14/// no more references to any of the tokens or nodes.13/// no more references to any of the tokens or nodes.
15pub fn parse(gpa: *Allocator, source: [:0]const u8) Allocator.Error!Tree {14pub fn parse(gpa: *Allocator, source: [:0]const u8) Allocator.Error!Ast {
16 var tokens = ast.TokenList{};15 var tokens = Ast.TokenList{};
17 defer tokens.deinit(gpa);16 defer tokens.deinit(gpa);
1817
19 // Empirically, the zig std lib has an 8:1 ratio of source bytes to token count.18 // 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 {...@@ -69,7 +68,7 @@ pub fn parse(gpa: *Allocator, source: [:0]const u8) Allocator.Error!Tree {
69 };68 };
7069
71 // TODO experiment with compacting the MultiArrayList slices here70 // TODO experiment with compacting the MultiArrayList slices here
72 return Tree{71 return Ast{
73 .source = source,72 .source = source,
74 .tokens = tokens.toOwnedSlice(),73 .tokens = tokens.toOwnedSlice(),
75 .nodes = parser.nodes.toOwnedSlice(),74 .nodes = parser.nodes.toOwnedSlice(),
...@@ -80,15 +79,15 @@ pub fn parse(gpa: *Allocator, source: [:0]const u8) Allocator.Error!Tree {...@@ -80,15 +79,15 @@ pub fn parse(gpa: *Allocator, source: [:0]const u8) Allocator.Error!Tree {
8079
81const null_node: Node.Index = 0;80const 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.
84const Parser = struct {83const Parser = struct {
85 gpa: *Allocator,84 gpa: *Allocator,
86 source: []const u8,85 source: []const u8,
87 token_tags: []const Token.Tag,86 token_tags: []const Token.Tag,
88 token_starts: []const ast.ByteOffset,87 token_starts: []const Ast.ByteOffset,
89 tok_i: TokenIndex,88 tok_i: TokenIndex,
90 errors: std.ArrayListUnmanaged(AstError),89 errors: std.ArrayListUnmanaged(AstError),
91 nodes: ast.NodeList,90 nodes: Ast.NodeList,
92 extra_data: std.ArrayListUnmanaged(Node.Index),91 extra_data: std.ArrayListUnmanaged(Node.Index),
93 scratch: std.ArrayListUnmanaged(Node.Index),92 scratch: std.ArrayListUnmanaged(Node.Index),
9493
...@@ -121,13 +120,13 @@ const Parser = struct {...@@ -121,13 +120,13 @@ const Parser = struct {
121 };120 };
122 }121 }
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 {
125 const result = @intCast(Node.Index, p.nodes.len);124 const result = @intCast(Node.Index, p.nodes.len);
126 try p.nodes.append(p.gpa, elem);125 try p.nodes.append(p.gpa, elem);
127 return result;126 return result;
128 }127 }
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 {
131 p.nodes.set(i, elem);130 p.nodes.set(i, elem);
132 return @intCast(Node.Index, i);131 return @intCast(Node.Index, i);
133 }132 }
...@@ -148,7 +147,7 @@ const Parser = struct {...@@ -148,7 +147,7 @@ const Parser = struct {
148 return result;147 return result;
149 }148 }
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 {
152 @setCold(true);151 @setCold(true);
153 try p.warnMsg(.{ .tag = tag, .token = p.tok_i });152 try p.warnMsg(.{ .tag = tag, .token = p.tok_i });
154 }153 }
...@@ -161,12 +160,12 @@ const Parser = struct {...@@ -161,12 +160,12 @@ const Parser = struct {
161 .extra = .{ .expected_tag = expected_token },160 .extra = .{ .expected_tag = expected_token },
162 });161 });
163 }162 }
164 fn warnMsg(p: *Parser, msg: ast.Error) error{OutOfMemory}!void {163 fn warnMsg(p: *Parser, msg: Ast.Error) error{OutOfMemory}!void {
165 @setCold(true);164 @setCold(true);
166 try p.errors.append(p.gpa, msg);165 try p.errors.append(p.gpa, msg);
167 }166 }
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 } {
170 @setCold(true);169 @setCold(true);
171 return p.failMsg(.{ .tag = tag, .token = p.tok_i });170 return p.failMsg(.{ .tag = tag, .token = p.tok_i });
172 }171 }
...@@ -180,7 +179,7 @@ const Parser = struct {...@@ -180,7 +179,7 @@ const Parser = struct {
180 });179 });
181 }180 }
182181
183 fn failMsg(p: *Parser, msg: ast.Error) error{ ParseError, OutOfMemory } {182 fn failMsg(p: *Parser, msg: Ast.Error) error{ ParseError, OutOfMemory } {
184 @setCold(true);183 @setCold(true);
185 try p.warnMsg(msg);184 try p.warnMsg(msg);
186 return error.ParseError;185 return error.ParseError;
lib/std/zig/parser_test.zig+1-1
...@@ -5308,7 +5308,7 @@ fn testCanonical(source: [:0]const u8) !void {...@@ -5308,7 +5308,7 @@ fn testCanonical(source: [:0]const u8) !void {
5308 return testTransform(source, source);5308 return testTransform(source, source);
5309}5309}
53105310
5311const Error = std.zig.ast.Error.Tag;5311const Error = std.zig.Ast.Error.Tag;
53125312
5313fn testError(source: [:0]const u8, expected_errors: []const Error) !void {5313fn testError(source: [:0]const u8, expected_errors: []const Error) !void {
5314 var tree = try std.zig.parse(std.testing.allocator, source);5314 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;...@@ -3,17 +3,17 @@ const assert = std.debug.assert;
3const mem = std.mem;3const mem = std.mem;
4const Allocator = std.mem.Allocator;4const Allocator = std.mem.Allocator;
5const meta = std.meta;5const meta = std.meta;
6const ast = std.zig.ast;6const Ast = std.zig.Ast;
7const Token = std.zig.Token;7const Token = std.zig.Token;
88
9const indent_delta = 4;9const indent_delta = 4;
10const asm_indent_delta = 2;10const asm_indent_delta = 2;
1111
12pub const Error = ast.Tree.RenderError;12pub const Error = Ast.RenderError;
1313
14const Ais = AutoIndentingStream(std.ArrayList(u8).Writer);14const 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 {
17 assert(tree.errors.len == 0); // Cannot render an invalid tree.17 assert(tree.errors.len == 0); // Cannot render an invalid tree.
18 var auto_indenting_stream = Ais{18 var auto_indenting_stream = Ais{
19 .indent_delta = indent_delta,19 .indent_delta = indent_delta,
...@@ -37,7 +37,7 @@ pub fn renderTree(buffer: *std.ArrayList(u8), tree: ast.Tree) Error!void {...@@ -37,7 +37,7 @@ pub fn renderTree(buffer: *std.ArrayList(u8), tree: ast.Tree) Error!void {
37}37}
3838
39/// Render all members in the given slice, keeping empty lines where appropriate39/// 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 {
41 if (members.len == 0) return;41 if (members.len == 0) return;
42 try renderMember(gpa, ais, tree, members[0], .newline);42 try renderMember(gpa, ais, tree, members[0], .newline);
43 for (members[1..]) |member| {43 for (members[1..]) |member| {
...@@ -46,7 +46,7 @@ fn renderMembers(gpa: *Allocator, ais: *Ais, tree: ast.Tree, members: []const as...@@ -46,7 +46,7 @@ fn renderMembers(gpa: *Allocator, ais: *Ais, tree: ast.Tree, members: []const as
46 }46 }
47}47}
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 {
50 const token_tags = tree.tokens.items(.tag);50 const token_tags = tree.tokens.items(.tag);
51 const main_tokens = tree.nodes.items(.main_token);51 const main_tokens = tree.nodes.items(.main_token);
52 const datas = tree.nodes.items(.data);52 const datas = tree.nodes.items(.data);
...@@ -83,9 +83,9 @@ fn renderMember(gpa: *Allocator, ais: *Ais, tree: ast.Tree, decl: ast.Node.Index...@@ -83,9 +83,9 @@ fn renderMember(gpa: *Allocator, ais: *Ais, tree: ast.Tree, decl: ast.Node.Index
83 switch (tree.nodes.items(.tag)[fn_proto]) {83 switch (tree.nodes.items(.tag)[fn_proto]) {
84 .fn_proto_one, .fn_proto => {84 .fn_proto_one, .fn_proto => {
85 const callconv_expr = if (tree.nodes.items(.tag)[fn_proto] == .fn_proto_one)85 const callconv_expr = if (tree.nodes.items(.tag)[fn_proto] == .fn_proto_one)
86 tree.extraData(datas[fn_proto].lhs, ast.Node.FnProtoOne).callconv_expr86 tree.extraData(datas[fn_proto].lhs, Ast.Node.FnProtoOne).callconv_expr
87 else87 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;
89 if (callconv_expr != 0 and tree.nodes.items(.tag)[callconv_expr] == .enum_literal) {89 if (callconv_expr != 0 and tree.nodes.items(.tag)[callconv_expr] == .enum_literal) {
90 if (mem.eql(u8, "Inline", tree.tokenSlice(main_tokens[callconv_expr]))) {90 if (mem.eql(u8, "Inline", tree.tokenSlice(main_tokens[callconv_expr]))) {
91 try ais.writer().writeAll("inline ");91 try ais.writer().writeAll("inline ");
...@@ -168,7 +168,7 @@ fn renderMember(gpa: *Allocator, ais: *Ais, tree: ast.Tree, decl: ast.Node.Index...@@ -168,7 +168,7 @@ fn renderMember(gpa: *Allocator, ais: *Ais, tree: ast.Tree, decl: ast.Node.Index
168}168}
169169
170/// Render all expressions in the slice, keeping empty lines where appropriate170/// 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 {
172 if (expressions.len == 0) return;172 if (expressions.len == 0) return;
173 try renderExpression(gpa, ais, tree, expressions[0], space);173 try renderExpression(gpa, ais, tree, expressions[0], space);
174 for (expressions[1..]) |expression| {174 for (expressions[1..]) |expression| {
...@@ -177,7 +177,7 @@ fn renderExpressions(gpa: *Allocator, ais: *Ais, tree: ast.Tree, expressions: []...@@ -177,7 +177,7 @@ fn renderExpressions(gpa: *Allocator, ais: *Ais, tree: ast.Tree, expressions: []
177 }177 }
178}178}
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 {
181 const token_tags = tree.tokens.items(.tag);181 const token_tags = tree.tokens.items(.tag);
182 const main_tokens = tree.nodes.items(.main_token);182 const main_tokens = tree.nodes.items(.main_token);
183 const node_tags = tree.nodes.items(.tag);183 const node_tags = tree.nodes.items(.tag);
...@@ -220,7 +220,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I...@@ -220,7 +220,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
220 .block_two,220 .block_two,
221 .block_two_semicolon,221 .block_two_semicolon,
222 => {222 => {
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 };
224 if (datas[node].lhs == 0) {224 if (datas[node].lhs == 0) {
225 return renderBlock(gpa, ais, tree, node, statements[0..0], space);225 return renderBlock(gpa, ais, tree, node, statements[0..0], space);
226 } else if (datas[node].rhs == 0) {226 } else if (datas[node].rhs == 0) {
...@@ -413,11 +413,11 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I...@@ -413,11 +413,11 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
413 .ptr_type_bit_range => return renderPtrType(gpa, ais, tree, tree.ptrTypeBitRange(node), space),413 .ptr_type_bit_range => return renderPtrType(gpa, ais, tree, tree.ptrTypeBitRange(node), space),
414414
415 .array_init_one, .array_init_one_comma => {415 .array_init_one, .array_init_one_comma => {
416 var elements: [1]ast.Node.Index = undefined;416 var elements: [1]Ast.Node.Index = undefined;
417 return renderArrayInit(gpa, ais, tree, tree.arrayInitOne(&elements, node), space);417 return renderArrayInit(gpa, ais, tree, tree.arrayInitOne(&elements, node), space);
418 },418 },
419 .array_init_dot_two, .array_init_dot_two_comma => {419 .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;
421 return renderArrayInit(gpa, ais, tree, tree.arrayInitDotTwo(&elements, node), space);421 return renderArrayInit(gpa, ais, tree, tree.arrayInitDotTwo(&elements, node), space);
422 },422 },
423 .array_init_dot,423 .array_init_dot,
...@@ -428,11 +428,11 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I...@@ -428,11 +428,11 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
428 => return renderArrayInit(gpa, ais, tree, tree.arrayInit(node), space),428 => return renderArrayInit(gpa, ais, tree, tree.arrayInit(node), space),
429429
430 .struct_init_one, .struct_init_one_comma => {430 .struct_init_one, .struct_init_one_comma => {
431 var fields: [1]ast.Node.Index = undefined;431 var fields: [1]Ast.Node.Index = undefined;
432 return renderStructInit(gpa, ais, tree, node, tree.structInitOne(&fields, node), space);432 return renderStructInit(gpa, ais, tree, node, tree.structInitOne(&fields, node), space);
433 },433 },
434 .struct_init_dot_two, .struct_init_dot_two_comma => {434 .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;
436 return renderStructInit(gpa, ais, tree, node, tree.structInitDotTwo(&fields, node), space);436 return renderStructInit(gpa, ais, tree, node, tree.structInitDotTwo(&fields, node), space);
437 },437 },
438 .struct_init_dot,438 .struct_init_dot,
...@@ -443,7 +443,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I...@@ -443,7 +443,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
443 => return renderStructInit(gpa, ais, tree, node, tree.structInit(node), space),443 => return renderStructInit(gpa, ais, tree, node, tree.structInit(node), space),
444444
445 .call_one, .call_one_comma, .async_call_one, .async_call_one_comma => {445 .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;
447 return renderCall(gpa, ais, tree, tree.callOne(&params, node), space);447 return renderCall(gpa, ais, tree, tree.callOne(&params, node), space);
448 },448 },
449449
...@@ -536,7 +536,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I...@@ -536,7 +536,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
536 => return renderContainerDecl(gpa, ais, tree, node, tree.containerDecl(node), space),536 => return renderContainerDecl(gpa, ais, tree, node, tree.containerDecl(node), space),
537537
538 .container_decl_two, .container_decl_two_trailing => {538 .container_decl_two, .container_decl_two_trailing => {
539 var buffer: [2]ast.Node.Index = undefined;539 var buffer: [2]Ast.Node.Index = undefined;
540 return renderContainerDecl(gpa, ais, tree, node, tree.containerDeclTwo(&buffer, node), space);540 return renderContainerDecl(gpa, ais, tree, node, tree.containerDeclTwo(&buffer, node), space);
541 },541 },
542 .container_decl_arg,542 .container_decl_arg,
...@@ -548,7 +548,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I...@@ -548,7 +548,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
548 => return renderContainerDecl(gpa, ais, tree, node, tree.taggedUnion(node), space),548 => return renderContainerDecl(gpa, ais, tree, node, tree.taggedUnion(node), space),
549549
550 .tagged_union_two, .tagged_union_two_trailing => {550 .tagged_union_two, .tagged_union_two_trailing => {
551 var buffer: [2]ast.Node.Index = undefined;551 var buffer: [2]Ast.Node.Index = undefined;
552 return renderContainerDecl(gpa, ais, tree, node, tree.taggedUnionTwo(&buffer, node), space);552 return renderContainerDecl(gpa, ais, tree, node, tree.taggedUnionTwo(&buffer, node), space);
553 },553 },
554 .tagged_union_enum_tag,554 .tagged_union_enum_tag,
...@@ -619,12 +619,12 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I...@@ -619,12 +619,12 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
619 },619 },
620620
621 .fn_proto_simple => {621 .fn_proto_simple => {
622 var params: [1]ast.Node.Index = undefined;622 var params: [1]Ast.Node.Index = undefined;
623 return renderFnProto(gpa, ais, tree, tree.fnProtoSimple(&params, node), space);623 return renderFnProto(gpa, ais, tree, tree.fnProtoSimple(&params, node), space);
624 },624 },
625 .fn_proto_multi => return renderFnProto(gpa, ais, tree, tree.fnProtoMulti(node), space),625 .fn_proto_multi => return renderFnProto(gpa, ais, tree, tree.fnProtoMulti(node), space),
626 .fn_proto_one => {626 .fn_proto_one => {
627 var params: [1]ast.Node.Index = undefined;627 var params: [1]Ast.Node.Index = undefined;
628 return renderFnProto(gpa, ais, tree, tree.fnProtoOne(&params, node), space);628 return renderFnProto(gpa, ais, tree, tree.fnProtoOne(&params, node), space);
629 },629 },
630 .fn_proto => return renderFnProto(gpa, ais, tree, tree.fnProto(node), space),630 .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...@@ -645,7 +645,7 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
645 => {645 => {
646 const switch_token = main_tokens[node];646 const switch_token = main_tokens[node];
647 const condition = datas[node].lhs;647 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);
649 const cases = tree.extra_data[extra.start..extra.end];649 const cases = tree.extra_data[extra.start..extra.end];
650 const rparen = tree.lastToken(condition) + 1;650 const rparen = tree.lastToken(condition) + 1;
651651
...@@ -704,8 +704,8 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I...@@ -704,8 +704,8 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
704fn renderArrayType(704fn renderArrayType(
705 gpa: *Allocator,705 gpa: *Allocator,
706 ais: *Ais,706 ais: *Ais,
707 tree: ast.Tree,707 tree: Ast,
708 array_type: ast.full.ArrayType,708 array_type: Ast.full.ArrayType,
709 space: Space,709 space: Space,
710) Error!void {710) Error!void {
711 const rbracket = tree.firstToken(array_type.ast.elem_type) - 1;711 const rbracket = tree.firstToken(array_type.ast.elem_type) - 1;
...@@ -726,8 +726,8 @@ fn renderArrayType(...@@ -726,8 +726,8 @@ fn renderArrayType(
726fn renderPtrType(726fn renderPtrType(
727 gpa: *Allocator,727 gpa: *Allocator,
728 ais: *Ais,728 ais: *Ais,
729 tree: ast.Tree,729 tree: Ast,
730 ptr_type: ast.full.PtrType,730 ptr_type: Ast.full.PtrType,
731 space: Space,731 space: Space,
732) Error!void {732) Error!void {
733 switch (ptr_type.size) {733 switch (ptr_type.size) {
...@@ -811,9 +811,9 @@ fn renderPtrType(...@@ -811,9 +811,9 @@ fn renderPtrType(
811fn renderSlice(811fn renderSlice(
812 gpa: *Allocator,812 gpa: *Allocator,
813 ais: *Ais,813 ais: *Ais,
814 tree: ast.Tree,814 tree: Ast,
815 slice_node: ast.Node.Index,815 slice_node: Ast.Node.Index,
816 slice: ast.full.Slice,816 slice: Ast.full.Slice,
817 space: Space,817 space: Space,
818) Error!void {818) Error!void {
819 const node_tags = tree.nodes.items(.tag);819 const node_tags = tree.nodes.items(.tag);
...@@ -847,8 +847,8 @@ fn renderSlice(...@@ -847,8 +847,8 @@ fn renderSlice(
847fn renderAsmOutput(847fn renderAsmOutput(
848 gpa: *Allocator,848 gpa: *Allocator,
849 ais: *Ais,849 ais: *Ais,
850 tree: ast.Tree,850 tree: Ast,
851 asm_output: ast.Node.Index,851 asm_output: Ast.Node.Index,
852 space: Space,852 space: Space,
853) Error!void {853) Error!void {
854 const token_tags = tree.tokens.items(.tag);854 const token_tags = tree.tokens.items(.tag);
...@@ -877,8 +877,8 @@ fn renderAsmOutput(...@@ -877,8 +877,8 @@ fn renderAsmOutput(
877fn renderAsmInput(877fn renderAsmInput(
878 gpa: *Allocator,878 gpa: *Allocator,
879 ais: *Ais,879 ais: *Ais,
880 tree: ast.Tree,880 tree: Ast,
881 asm_input: ast.Node.Index,881 asm_input: Ast.Node.Index,
882 space: Space,882 space: Space,
883) Error!void {883) Error!void {
884 const node_tags = tree.nodes.items(.tag);884 const node_tags = tree.nodes.items(.tag);
...@@ -896,7 +896,7 @@ fn renderAsmInput(...@@ -896,7 +896,7 @@ fn renderAsmInput(
896 return renderToken(ais, tree, datas[asm_input].rhs, space); // rparen896 return renderToken(ais, tree, datas[asm_input].rhs, space); // rparen
897}897}
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 {
900 if (var_decl.visib_token) |visib_token| {900 if (var_decl.visib_token) |visib_token| {
901 try renderToken(ais, tree, visib_token, Space.space); // pub901 try renderToken(ais, tree, visib_token, Space.space); // pub
902 }902 }
...@@ -985,7 +985,7 @@ fn renderVarDecl(gpa: *Allocator, ais: *Ais, tree: ast.Tree, var_decl: ast.full....@@ -985,7 +985,7 @@ fn renderVarDecl(gpa: *Allocator, ais: *Ais, tree: ast.Tree, var_decl: ast.full.
985 return renderToken(ais, tree, var_decl.ast.mut_token + 2, .newline); // ;985 return renderToken(ais, tree, var_decl.ast.mut_token + 2, .newline); // ;
986}986}
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 {
989 return renderWhile(gpa, ais, tree, .{989 return renderWhile(gpa, ais, tree, .{
990 .ast = .{990 .ast = .{
991 .while_token = if_node.ast.if_token,991 .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...@@ -1004,7 +1004,7 @@ fn renderIf(gpa: *Allocator, ais: *Ais, tree: ast.Tree, if_node: ast.full.If, sp
10041004
1005/// Note that this function is additionally used to render if and for expressions, with1005/// Note that this function is additionally used to render if and for expressions, with
1006/// respective values set to null.1006/// 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 {
1008 const node_tags = tree.nodes.items(.tag);1008 const node_tags = tree.nodes.items(.tag);
1009 const token_tags = tree.tokens.items(.tag);1009 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....@@ -1109,8 +1109,8 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full.
1109fn renderContainerField(1109fn renderContainerField(
1110 gpa: *Allocator,1110 gpa: *Allocator,
1111 ais: *Ais,1111 ais: *Ais,
1112 tree: ast.Tree,1112 tree: Ast,
1113 field: ast.full.ContainerField,1113 field: Ast.full.ContainerField,
1114 space: Space,1114 space: Space,
1115) Error!void {1115) Error!void {
1116 if (field.comptime_token) |t| {1116 if (field.comptime_token) |t| {
...@@ -1183,9 +1183,9 @@ fn renderContainerField(...@@ -1183,9 +1183,9 @@ fn renderContainerField(
1183fn renderBuiltinCall(1183fn renderBuiltinCall(
1184 gpa: *Allocator,1184 gpa: *Allocator,
1185 ais: *Ais,1185 ais: *Ais,
1186 tree: ast.Tree,1186 tree: Ast,
1187 builtin_token: ast.TokenIndex,1187 builtin_token: Ast.TokenIndex,
1188 params: []const ast.Node.Index,1188 params: []const Ast.Node.Index,
1189 space: Space,1189 space: Space,
1190) Error!void {1190) Error!void {
1191 const token_tags = tree.tokens.items(.tag);1191 const token_tags = tree.tokens.items(.tag);
...@@ -1238,7 +1238,7 @@ fn renderBuiltinCall(...@@ -1238,7 +1238,7 @@ fn renderBuiltinCall(
1238 }1238 }
1239}1239}
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 {
1242 const token_tags = tree.tokens.items(.tag);1242 const token_tags = tree.tokens.items(.tag);
1243 const token_starts = tree.tokens.items(.start);1243 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....@@ -1438,8 +1438,8 @@ fn renderFnProto(gpa: *Allocator, ais: *Ais, tree: ast.Tree, fn_proto: ast.full.
1438fn renderSwitchCase(1438fn renderSwitchCase(
1439 gpa: *Allocator,1439 gpa: *Allocator,
1440 ais: *Ais,1440 ais: *Ais,
1441 tree: ast.Tree,1441 tree: Ast,
1442 switch_case: ast.full.SwitchCase,1442 switch_case: Ast.full.SwitchCase,
1443 space: Space,1443 space: Space,
1444) Error!void {1444) Error!void {
1445 const node_tags = tree.nodes.items(.tag);1445 const node_tags = tree.nodes.items(.tag);
...@@ -1491,9 +1491,9 @@ fn renderSwitchCase(...@@ -1491,9 +1491,9 @@ fn renderSwitchCase(
1491fn renderBlock(1491fn renderBlock(
1492 gpa: *Allocator,1492 gpa: *Allocator,
1493 ais: *Ais,1493 ais: *Ais,
1494 tree: ast.Tree,1494 tree: Ast,
1495 block_node: ast.Node.Index,1495 block_node: Ast.Node.Index,
1496 statements: []const ast.Node.Index,1496 statements: []const Ast.Node.Index,
1497 space: Space,1497 space: Space,
1498) Error!void {1498) Error!void {
1499 const token_tags = tree.tokens.items(.tag);1499 const token_tags = tree.tokens.items(.tag);
...@@ -1531,9 +1531,9 @@ fn renderBlock(...@@ -1531,9 +1531,9 @@ fn renderBlock(
1531fn renderStructInit(1531fn renderStructInit(
1532 gpa: *Allocator,1532 gpa: *Allocator,
1533 ais: *Ais,1533 ais: *Ais,
1534 tree: ast.Tree,1534 tree: Ast,
1535 struct_node: ast.Node.Index,1535 struct_node: Ast.Node.Index,
1536 struct_init: ast.full.StructInit,1536 struct_init: Ast.full.StructInit,
1537 space: Space,1537 space: Space,
1538) Error!void {1538) Error!void {
1539 const token_tags = tree.tokens.items(.tag);1539 const token_tags = tree.tokens.items(.tag);
...@@ -1590,8 +1590,8 @@ fn renderStructInit(...@@ -1590,8 +1590,8 @@ fn renderStructInit(
1590fn renderArrayInit(1590fn renderArrayInit(
1591 gpa: *Allocator,1591 gpa: *Allocator,
1592 ais: *Ais,1592 ais: *Ais,
1593 tree: ast.Tree,1593 tree: Ast,
1594 array_init: ast.full.ArrayInit,1594 array_init: Ast.full.ArrayInit,
1595 space: Space,1595 space: Space,
1596) Error!void {1596) Error!void {
1597 const token_tags = tree.tokens.items(.tag);1597 const token_tags = tree.tokens.items(.tag);
...@@ -1787,9 +1787,9 @@ fn renderArrayInit(...@@ -1787,9 +1787,9 @@ fn renderArrayInit(
1787fn renderContainerDecl(1787fn renderContainerDecl(
1788 gpa: *Allocator,1788 gpa: *Allocator,
1789 ais: *Ais,1789 ais: *Ais,
1790 tree: ast.Tree,1790 tree: Ast,
1791 container_decl_node: ast.Node.Index,1791 container_decl_node: Ast.Node.Index,
1792 container_decl: ast.full.ContainerDecl,1792 container_decl: Ast.full.ContainerDecl,
1793 space: Space,1793 space: Space,
1794) Error!void {1794) Error!void {
1795 const token_tags = tree.tokens.items(.tag);1795 const token_tags = tree.tokens.items(.tag);
...@@ -1799,7 +1799,7 @@ fn renderContainerDecl(...@@ -1799,7 +1799,7 @@ fn renderContainerDecl(
1799 try renderToken(ais, tree, layout_token, .space);1799 try renderToken(ais, tree, layout_token, .space);
1800 }1800 }
18011801
1802 var lbrace: ast.TokenIndex = undefined;1802 var lbrace: Ast.TokenIndex = undefined;
1803 if (container_decl.ast.enum_token) |enum_token| {1803 if (container_decl.ast.enum_token) |enum_token| {
1804 try renderToken(ais, tree, container_decl.ast.main_token, .none); // union1804 try renderToken(ais, tree, container_decl.ast.main_token, .none); // union
1805 try renderToken(ais, tree, enum_token - 1, .none); // lparen1805 try renderToken(ais, tree, enum_token - 1, .none); // lparen
...@@ -1869,8 +1869,8 @@ fn renderContainerDecl(...@@ -1869,8 +1869,8 @@ fn renderContainerDecl(
1869fn renderAsm(1869fn renderAsm(
1870 gpa: *Allocator,1870 gpa: *Allocator,
1871 ais: *Ais,1871 ais: *Ais,
1872 tree: ast.Tree,1872 tree: Ast,
1873 asm_node: ast.full.Asm,1873 asm_node: Ast.full.Asm,
1874 space: Space,1874 space: Space,
1875) Error!void {1875) Error!void {
1876 const token_tags = tree.tokens.items(.tag);1876 const token_tags = tree.tokens.items(.tag);
...@@ -2018,8 +2018,8 @@ fn renderAsm(...@@ -2018,8 +2018,8 @@ fn renderAsm(
2018fn renderCall(2018fn renderCall(
2019 gpa: *Allocator,2019 gpa: *Allocator,
2020 ais: *Ais,2020 ais: *Ais,
2021 tree: ast.Tree,2021 tree: Ast,
2022 call: ast.full.Call,2022 call: Ast.full.Call,
2023 space: Space,2023 space: Space,
2024) Error!void {2024) Error!void {
2025 const token_tags = tree.tokens.items(.tag);2025 const token_tags = tree.tokens.items(.tag);
...@@ -2091,7 +2091,7 @@ fn renderCall(...@@ -2091,7 +2091,7 @@ fn renderCall(
20912091
2092/// Renders the given expression indented, popping the indent before rendering2092/// Renders the given expression indented, popping the indent before rendering
2093/// any following line comments2093/// 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 {
2095 const token_starts = tree.tokens.items(.start);2095 const token_starts = tree.tokens.items(.start);
2096 const token_tags = tree.tokens.items(.tag);2096 const token_tags = tree.tokens.items(.tag);
20972097
...@@ -2148,7 +2148,7 @@ fn renderExpressionIndented(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: as...@@ -2148,7 +2148,7 @@ fn renderExpressionIndented(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: as
2148}2148}
21492149
2150/// Render an expression, and the comma that follows it, if it is present in the source.2150/// 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 {
2152 const token_tags = tree.tokens.items(.tag);2152 const token_tags = tree.tokens.items(.tag);
2153 const maybe_comma = tree.lastToken(node) + 1;2153 const maybe_comma = tree.lastToken(node) + 1;
2154 if (token_tags[maybe_comma] == .comma) {2154 if (token_tags[maybe_comma] == .comma) {
...@@ -2159,7 +2159,7 @@ fn renderExpressionComma(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.N...@@ -2159,7 +2159,7 @@ fn renderExpressionComma(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.N
2159 }2159 }
2160}2160}
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 {
2163 const token_tags = tree.tokens.items(.tag);2163 const token_tags = tree.tokens.items(.tag);
2164 const maybe_comma = token + 1;2164 const maybe_comma = token + 1;
2165 if (token_tags[maybe_comma] == .comma) {2165 if (token_tags[maybe_comma] == .comma) {
...@@ -2191,7 +2191,7 @@ const Space = enum {...@@ -2191,7 +2191,7 @@ const Space = enum {
2191 skip,2191 skip,
2192};2192};
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 {
2195 const token_tags = tree.tokens.items(.tag);2195 const token_tags = tree.tokens.items(.tag);
2196 const token_starts = tree.tokens.items(.start);2196 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...@@ -2238,7 +2238,7 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp
2238/// `start_token` to `end_token`. This is used to determine if e.g. a2238/// `start_token` to `end_token`. This is used to determine if e.g. a
2239/// fn_proto should be wrapped and have a trailing comma inserted even if2239/// fn_proto should be wrapped and have a trailing comma inserted even if
2240/// there is none in the source.2240/// 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 {
2242 const token_starts = tree.tokens.items(.start);2242 const token_starts = tree.tokens.items(.start);
22432243
2244 var i = start_token;2244 var i = start_token;
...@@ -2253,7 +2253,7 @@ fn hasComment(tree: ast.Tree, start_token: ast.TokenIndex, end_token: ast.TokenI...@@ -2253,7 +2253,7 @@ fn hasComment(tree: ast.Tree, start_token: ast.TokenIndex, end_token: ast.TokenI
22532253
2254/// Returns true if there exists a multiline string literal between the start2254/// Returns true if there exists a multiline string literal between the start
2255/// of token `start_token` and the start of token `end_token`.2255/// 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 {
2257 const token_tags = tree.tokens.items(.tag);2257 const token_tags = tree.tokens.items(.tag);
22582258
2259 for (token_tags[start_token..end_token]) |tag| {2259 for (token_tags[start_token..end_token]) |tag| {
...@@ -2268,7 +2268,7 @@ fn hasMultilineString(tree: ast.Tree, start_token: ast.TokenIndex, end_token: as...@@ -2268,7 +2268,7 @@ fn hasMultilineString(tree: ast.Tree, start_token: ast.TokenIndex, end_token: as
22682268
2269/// Assumes that start is the first byte past the previous token and2269/// Assumes that start is the first byte past the previous token and
2270/// that end is the last byte before the next token.2270/// 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 {
2272 var index: usize = start;2272 var index: usize = start;
2273 while (mem.indexOf(u8, tree.source[index..end], "//")) |offset| {2273 while (mem.indexOf(u8, tree.source[index..end], "//")) |offset| {
2274 const comment_start = index + offset;2274 const comment_start = index + offset;
...@@ -2325,12 +2325,12 @@ fn renderComments(ais: *Ais, tree: ast.Tree, start: usize, end: usize) Error!boo...@@ -2325,12 +2325,12 @@ fn renderComments(ais: *Ais, tree: ast.Tree, start: usize, end: usize) Error!boo
2325 return index != start;2325 return index != start;
2326}2326}
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 {
2329 return renderExtraNewlineToken(ais, tree, tree.firstToken(node));2329 return renderExtraNewlineToken(ais, tree, tree.firstToken(node));
2330}2330}
23312331
2332/// Check if there is an empty line immediately before the given token. If so, render it.2332/// 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 {
2334 const token_starts = tree.tokens.items(.start);2334 const token_starts = tree.tokens.items(.start);
2335 const token_start = token_starts[token_index];2335 const token_start = token_starts[token_index];
2336 if (token_start == 0) return;2336 if (token_start == 0) return;
...@@ -2355,7 +2355,7 @@ fn renderExtraNewlineToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenInde...@@ -2355,7 +2355,7 @@ fn renderExtraNewlineToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenInde
23552355
2356/// end_token is the token one past the last doc comment token. This function2356/// end_token is the token one past the last doc comment token. This function
2357/// searches backwards from there.2357/// 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 {
2359 // Search backwards for the first doc comment.2359 // Search backwards for the first doc comment.
2360 const token_tags = tree.tokens.items(.tag);2360 const token_tags = tree.tokens.items(.tag);
2361 if (end_token == 0) return;2361 if (end_token == 0) return;
...@@ -2376,7 +2376,7 @@ fn renderDocComments(ais: *Ais, tree: ast.Tree, end_token: ast.TokenIndex) Error...@@ -2376,7 +2376,7 @@ fn renderDocComments(ais: *Ais, tree: ast.Tree, end_token: ast.TokenIndex) Error
2376}2376}
23772377
2378/// start_token is first container doc comment token.2378/// 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 {
2380 const token_tags = tree.tokens.items(.tag);2380 const token_tags = tree.tokens.items(.tag);
2381 var tok = start_token;2381 var tok = start_token;
2382 while (token_tags[tok] == .container_doc_comment) : (tok += 1) {2382 while (token_tags[tok] == .container_doc_comment) : (tok += 1) {
...@@ -2390,7 +2390,7 @@ fn renderContainerDocComments(ais: *Ais, tree: ast.Tree, start_token: ast.TokenI...@@ -2390,7 +2390,7 @@ fn renderContainerDocComments(ais: *Ais, tree: ast.Tree, start_token: ast.TokenI
2390 }2390 }
2391}2391}
23922392
2393fn tokenSliceForRender(tree: ast.Tree, token_index: ast.TokenIndex) []const u8 {2393fn tokenSliceForRender(tree: Ast, token_index: Ast.TokenIndex) []const u8 {
2394 var ret = tree.tokenSlice(token_index);2394 var ret = tree.tokenSlice(token_index);
2395 if (tree.tokens.items(.tag)[token_index] == .multiline_string_literal_line) {2395 if (tree.tokens.items(.tag)[token_index] == .multiline_string_literal_line) {
2396 assert(ret[ret.len - 1] == '\n');2396 assert(ret[ret.len - 1] == '\n');
...@@ -2399,7 +2399,7 @@ fn tokenSliceForRender(tree: ast.Tree, token_index: ast.TokenIndex) []const u8 {...@@ -2399,7 +2399,7 @@ fn tokenSliceForRender(tree: ast.Tree, token_index: ast.TokenIndex) []const u8 {
2399 return ret;2399 return ret;
2400}2400}
24012401
2402fn hasSameLineComment(tree: ast.Tree, token_index: ast.TokenIndex) bool {2402fn hasSameLineComment(tree: Ast, token_index: Ast.TokenIndex) bool {
2403 const token_starts = tree.tokens.items(.start);2403 const token_starts = tree.tokens.items(.start);
2404 const between_source = tree.source[token_starts[token_index]..token_starts[token_index + 1]];2404 const between_source = tree.source[token_starts[token_index]..token_starts[token_index + 1]];
2405 for (between_source) |byte| switch (byte) {2405 for (between_source) |byte| switch (byte) {
...@@ -2412,7 +2412,7 @@ fn hasSameLineComment(tree: ast.Tree, token_index: ast.TokenIndex) bool {...@@ -2412,7 +2412,7 @@ fn hasSameLineComment(tree: ast.Tree, token_index: ast.TokenIndex) bool {
24122412
2413/// Returns `true` if and only if there are any tokens or line comments between2413/// Returns `true` if and only if there are any tokens or line comments between
2414/// start_token and end_token.2414/// 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 {
2416 if (start_token + 1 != end_token) return true;2416 if (start_token + 1 != end_token) return true;
2417 const token_starts = tree.tokens.items(.start);2417 const token_starts = tree.tokens.items(.start);
2418 const between_source = tree.source[token_starts[start_token]..token_starts[start_token + 1]];2418 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...@@ -2431,7 +2431,7 @@ fn writeFixingWhitespace(writer: std.ArrayList(u8).Writer, slice: []const u8) Er
2431 };2431 };
2432}2432}
24332433
2434fn nodeIsBlock(tag: ast.Node.Tag) bool {2434fn nodeIsBlock(tag: Ast.Node.Tag) bool {
2435 return switch (tag) {2435 return switch (tag) {
2436 .block,2436 .block,
2437 .block_semicolon,2437 .block_semicolon,
...@@ -2450,7 +2450,7 @@ fn nodeIsBlock(tag: ast.Node.Tag) bool {...@@ -2450,7 +2450,7 @@ fn nodeIsBlock(tag: ast.Node.Tag) bool {
2450 };2450 };
2451}2451}
24522452
2453fn nodeIsIfForWhileSwitch(tag: ast.Node.Tag) bool {2453fn nodeIsIfForWhileSwitch(tag: Ast.Node.Tag) bool {
2454 return switch (tag) {2454 return switch (tag) {
2455 .@"if",2455 .@"if",
2456 .if_simple,2456 .if_simple,
...@@ -2466,7 +2466,7 @@ fn nodeIsIfForWhileSwitch(tag: ast.Node.Tag) bool {...@@ -2466,7 +2466,7 @@ fn nodeIsIfForWhileSwitch(tag: ast.Node.Tag) bool {
2466 };2466 };
2467}2467}
24682468
2469fn nodeCausesSliceOpSpace(tag: ast.Node.Tag) bool {2469fn nodeCausesSliceOpSpace(tag: Ast.Node.Tag) bool {
2470 return switch (tag) {2470 return switch (tag) {
2471 .@"catch",2471 .@"catch",
2472 .add,2472 .add,
...@@ -2516,7 +2516,7 @@ fn nodeCausesSliceOpSpace(tag: ast.Node.Tag) bool {...@@ -2516,7 +2516,7 @@ fn nodeCausesSliceOpSpace(tag: ast.Node.Tag) bool {
2516}2516}
25172517
2518// Returns the number of nodes in `expr` that are on the same line as `rtoken`.2518// 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 {
2520 const token_tags = tree.tokens.items(.tag);2520 const token_tags = tree.tokens.items(.tag);
25212521
2522 const first_token = tree.firstToken(exprs[0]);2522 const first_token = tree.firstToken(exprs[0]);
src/AstGen.zig+252-252
...@@ -2,7 +2,7 @@...@@ -2,7 +2,7 @@
2const AstGen = @This();2const AstGen = @This();
33
4const std = @import("std");4const std = @import("std");
5const ast = std.zig.ast;5const Ast = std.zig.Ast;
6const mem = std.mem;6const mem = std.mem;
7const Allocator = std.mem.Allocator;7const Allocator = std.mem.Allocator;
8const assert = std.debug.assert;8const assert = std.debug.assert;
...@@ -13,7 +13,7 @@ const trace = @import("tracy.zig").trace;...@@ -13,7 +13,7 @@ const trace = @import("tracy.zig").trace;
13const BuiltinFn = @import("BuiltinFn.zig");13const BuiltinFn = @import("BuiltinFn.zig");
1414
15gpa: *Allocator,15gpa: *Allocator,
16tree: *const ast.Tree,16tree: *const Ast,
17instructions: std.MultiArrayList(Zir.Inst) = .{},17instructions: std.MultiArrayList(Zir.Inst) = .{},
18extra: ArrayListUnmanaged(u32) = .{},18extra: ArrayListUnmanaged(u32) = .{},
19string_bytes: ArrayListUnmanaged(u8) = .{},19string_bytes: ArrayListUnmanaged(u8) = .{},
...@@ -36,7 +36,7 @@ compile_errors: ArrayListUnmanaged(Zir.Inst.CompileErrors.Item) = .{},...@@ -36,7 +36,7 @@ compile_errors: ArrayListUnmanaged(Zir.Inst.CompileErrors.Item) = .{},
36fn_block: ?*GenZir = null,36fn_block: ?*GenZir = null,
37/// Maps string table indexes to the first `@import` ZIR instruction37/// Maps string table indexes to the first `@import` ZIR instruction
38/// that uses this string as the operand.38/// that uses this string as the operand.
39imports: std.AutoArrayHashMapUnmanaged(u32, ast.TokenIndex) = .{},39imports: std.AutoArrayHashMapUnmanaged(u32, Ast.TokenIndex) = .{},
4040
41const InnerError = error{ OutOfMemory, AnalysisFail };41const InnerError = error{ OutOfMemory, AnalysisFail };
4242
...@@ -70,7 +70,7 @@ fn appendRefsAssumeCapacity(astgen: *AstGen, refs: []const Zir.Inst.Ref) void {...@@ -70,7 +70,7 @@ fn appendRefsAssumeCapacity(astgen: *AstGen, refs: []const Zir.Inst.Ref) void {
70 astgen.extra.appendSliceAssumeCapacity(coerced);70 astgen.extra.appendSliceAssumeCapacity(coerced);
71}71}
7272
73pub fn generate(gpa: *Allocator, tree: ast.Tree) Allocator.Error!Zir {73pub fn generate(gpa: *Allocator, tree: Ast) Allocator.Error!Zir {
74 var arena = std.heap.ArenaAllocator.init(gpa);74 var arena = std.heap.ArenaAllocator.init(gpa);
75 defer arena.deinit();75 defer arena.deinit();
7676
...@@ -106,7 +106,7 @@ pub fn generate(gpa: *Allocator, tree: ast.Tree) Allocator.Error!Zir {...@@ -106,7 +106,7 @@ pub fn generate(gpa: *Allocator, tree: ast.Tree) Allocator.Error!Zir {
106 };106 };
107 defer gen_scope.instructions.deinit(gpa);107 defer gen_scope.instructions.deinit(gpa);
108108
109 const container_decl: ast.full.ContainerDecl = .{109 const container_decl: Ast.full.ContainerDecl = .{
110 .layout_token = null,110 .layout_token = null,
111 .ast = .{111 .ast = .{
112 .main_token = undefined,112 .main_token = undefined,
...@@ -265,7 +265,7 @@ pub const bool_rl: ResultLoc = .{ .ty = .bool_type };...@@ -265,7 +265,7 @@ pub const bool_rl: ResultLoc = .{ .ty = .bool_type };
265pub const type_rl: ResultLoc = .{ .ty = .type_type };265pub const type_rl: ResultLoc = .{ .ty = .type_type };
266pub const coerced_type_rl: ResultLoc = .{ .coerced_ty = .type_type };266pub 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 {
269 const prev_force_comptime = gz.force_comptime;269 const prev_force_comptime = gz.force_comptime;
270 gz.force_comptime = true;270 gz.force_comptime = true;
271 defer gz.force_comptime = prev_force_comptime;271 defer gz.force_comptime = prev_force_comptime;
...@@ -278,8 +278,8 @@ fn reachableExpr(...@@ -278,8 +278,8 @@ fn reachableExpr(
278 gz: *GenZir,278 gz: *GenZir,
279 scope: *Scope,279 scope: *Scope,
280 rl: ResultLoc,280 rl: ResultLoc,
281 node: ast.Node.Index,281 node: Ast.Node.Index,
282 src_node: ast.Node.Index,282 src_node: Ast.Node.Index,
283) InnerError!Zir.Inst.Ref {283) InnerError!Zir.Inst.Ref {
284 const result_inst = try expr(gz, scope, rl, node);284 const result_inst = try expr(gz, scope, rl, node);
285 if (gz.refIsNoReturn(result_inst)) {285 if (gz.refIsNoReturn(result_inst)) {
...@@ -290,7 +290,7 @@ fn reachableExpr(...@@ -290,7 +290,7 @@ fn reachableExpr(
290 return result_inst;290 return result_inst;
291}291}
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 {
294 const astgen = gz.astgen;294 const astgen = gz.astgen;
295 const tree = astgen.tree;295 const tree = astgen.tree;
296 const node_tags = tree.nodes.items(.tag);296 const node_tags = tree.nodes.items(.tag);
...@@ -481,7 +481,7 @@ fn lvalExpr(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Ins...@@ -481,7 +481,7 @@ fn lvalExpr(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Ins
481/// When `rl` is discard, ptr, inferred_ptr, or inferred_ptr, the481/// When `rl` is discard, ptr, inferred_ptr, or inferred_ptr, the
482/// result instruction can be used to inspect whether it is isNoReturn() but that is it,482/// result instruction can be used to inspect whether it is isNoReturn() but that is it,
483/// it must otherwise not be used.483/// 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 {
485 const astgen = gz.astgen;485 const astgen = gz.astgen;
486 const tree = astgen.tree;486 const tree = astgen.tree;
487 const main_tokens = tree.nodes.items(.main_token);487 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...@@ -640,13 +640,13 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
640640
641 .builtin_call_two, .builtin_call_two_comma => {641 .builtin_call_two, .builtin_call_two_comma => {
642 if (node_datas[node].lhs == 0) {642 if (node_datas[node].lhs == 0) {
643 const params = [_]ast.Node.Index{};643 const params = [_]Ast.Node.Index{};
644 return builtinCall(gz, scope, rl, node, &params);644 return builtinCall(gz, scope, rl, node, &params);
645 } else if (node_datas[node].rhs == 0) {645 } 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};
647 return builtinCall(gz, scope, rl, node, &params);647 return builtinCall(gz, scope, rl, node, &params);
648 } else {648 } 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 };
650 return builtinCall(gz, scope, rl, node, &params);650 return builtinCall(gz, scope, rl, node, &params);
651 }651 }
652 },652 },
...@@ -656,7 +656,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -656,7 +656,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
656 },656 },
657657
658 .call_one, .call_one_comma, .async_call_one, .async_call_one_comma => {658 .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;
660 return callExpr(gz, scope, rl, node, tree.callOne(&params, node));660 return callExpr(gz, scope, rl, node, tree.callOne(&params, node));
661 },661 },
662 .call, .call_comma, .async_call, .async_call_comma => {662 .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...@@ -704,7 +704,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
704 },704 },
705 .slice => {705 .slice => {
706 const lhs = try expr(gz, scope, .ref, node_datas[node].lhs);706 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);
708 const start = try expr(gz, scope, .{ .ty = .usize_type }, extra.start);708 const start = try expr(gz, scope, .{ .ty = .usize_type }, extra.start);
709 const end = try expr(gz, scope, .{ .ty = .usize_type }, extra.end);709 const end = try expr(gz, scope, .{ .ty = .usize_type }, extra.end);
710 const result = try gz.addPlNode(.slice_end, node, Zir.Inst.SliceEnd{710 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...@@ -722,7 +722,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
722 },722 },
723 .slice_sentinel => {723 .slice_sentinel => {
724 const lhs = try expr(gz, scope, .ref, node_datas[node].lhs);724 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);
726 const start = try expr(gz, scope, .{ .ty = .usize_type }, extra.start);726 const start = try expr(gz, scope, .{ .ty = .usize_type }, extra.start);
727 const end = if (extra.end != 0) try expr(gz, scope, .{ .ty = .usize_type }, extra.end) else .none;727 const end = if (extra.end != 0) try expr(gz, scope, .{ .ty = .usize_type }, extra.end) else .none;
728 const sentinel = try expr(gz, scope, .{ .ty = .usize_type }, extra.sentinel);728 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...@@ -773,7 +773,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
773 ), node),773 ), node),
774 },774 },
775 .block_two, .block_two_semicolon => {775 .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 };
777 if (node_datas[node].lhs == 0) {777 if (node_datas[node].lhs == 0) {
778 return blockExpr(gz, scope, rl, node, statements[0..0]);778 return blockExpr(gz, scope, rl, node, statements[0..0]);
779 } else if (node_datas[node].rhs == 0) {779 } else if (node_datas[node].rhs == 0) {
...@@ -796,7 +796,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -796,7 +796,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
796 },796 },
797 .@"catch" => {797 .@"catch" => {
798 const catch_token = main_tokens[node];798 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)
800 catch_token + 2800 catch_token + 2
801 else801 else
802 null;802 null;
...@@ -863,7 +863,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -863,7 +863,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
863 .container_decl_trailing,863 .container_decl_trailing,
864 => return containerDecl(gz, scope, rl, node, tree.containerDecl(node)),864 => return containerDecl(gz, scope, rl, node, tree.containerDecl(node)),
865 .container_decl_two, .container_decl_two_trailing => {865 .container_decl_two, .container_decl_two_trailing => {
866 var buffer: [2]ast.Node.Index = undefined;866 var buffer: [2]Ast.Node.Index = undefined;
867 return containerDecl(gz, scope, rl, node, tree.containerDeclTwo(&buffer, node));867 return containerDecl(gz, scope, rl, node, tree.containerDeclTwo(&buffer, node));
868 },868 },
869 .container_decl_arg,869 .container_decl_arg,
...@@ -874,7 +874,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -874,7 +874,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
874 .tagged_union_trailing,874 .tagged_union_trailing,
875 => return containerDecl(gz, scope, rl, node, tree.taggedUnion(node)),875 => return containerDecl(gz, scope, rl, node, tree.taggedUnion(node)),
876 .tagged_union_two, .tagged_union_two_trailing => {876 .tagged_union_two, .tagged_union_two_trailing => {
877 var buffer: [2]ast.Node.Index = undefined;877 var buffer: [2]Ast.Node.Index = undefined;
878 return containerDecl(gz, scope, rl, node, tree.taggedUnionTwo(&buffer, node));878 return containerDecl(gz, scope, rl, node, tree.taggedUnionTwo(&buffer, node));
879 },879 },
880 .tagged_union_enum_tag,880 .tagged_union_enum_tag,
...@@ -900,11 +900,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -900,11 +900,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
900 .@"try" => return tryExpr(gz, scope, rl, node, node_datas[node].lhs),900 .@"try" => return tryExpr(gz, scope, rl, node, node_datas[node].lhs),
901901
902 .array_init_one, .array_init_one_comma => {902 .array_init_one, .array_init_one_comma => {
903 var elements: [1]ast.Node.Index = undefined;903 var elements: [1]Ast.Node.Index = undefined;
904 return arrayInitExpr(gz, scope, rl, node, tree.arrayInitOne(&elements, node));904 return arrayInitExpr(gz, scope, rl, node, tree.arrayInitOne(&elements, node));
905 },905 },
906 .array_init_dot_two, .array_init_dot_two_comma => {906 .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;
908 return arrayInitExpr(gz, scope, rl, node, tree.arrayInitDotTwo(&elements, node));908 return arrayInitExpr(gz, scope, rl, node, tree.arrayInitDotTwo(&elements, node));
909 },909 },
910 .array_init_dot,910 .array_init_dot,
...@@ -915,11 +915,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -915,11 +915,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
915 => return arrayInitExpr(gz, scope, rl, node, tree.arrayInit(node)),915 => return arrayInitExpr(gz, scope, rl, node, tree.arrayInit(node)),
916916
917 .struct_init_one, .struct_init_one_comma => {917 .struct_init_one, .struct_init_one_comma => {
918 var fields: [1]ast.Node.Index = undefined;918 var fields: [1]Ast.Node.Index = undefined;
919 return structInitExpr(gz, scope, rl, node, tree.structInitOne(&fields, node));919 return structInitExpr(gz, scope, rl, node, tree.structInitOne(&fields, node));
920 },920 },
921 .struct_init_dot_two, .struct_init_dot_two_comma => {921 .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;
923 return structInitExpr(gz, scope, rl, node, tree.structInitDotTwo(&fields, node));923 return structInitExpr(gz, scope, rl, node, tree.structInitDotTwo(&fields, node));
924 },924 },
925 .struct_init_dot,925 .struct_init_dot,
...@@ -930,14 +930,14 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -930,14 +930,14 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
930 => return structInitExpr(gz, scope, rl, node, tree.structInit(node)),930 => return structInitExpr(gz, scope, rl, node, tree.structInit(node)),
931931
932 .fn_proto_simple => {932 .fn_proto_simple => {
933 var params: [1]ast.Node.Index = undefined;933 var params: [1]Ast.Node.Index = undefined;
934 return fnProtoExpr(gz, scope, rl, tree.fnProtoSimple(&params, node));934 return fnProtoExpr(gz, scope, rl, tree.fnProtoSimple(&params, node));
935 },935 },
936 .fn_proto_multi => {936 .fn_proto_multi => {
937 return fnProtoExpr(gz, scope, rl, tree.fnProtoMulti(node));937 return fnProtoExpr(gz, scope, rl, tree.fnProtoMulti(node));
938 },938 },
939 .fn_proto_one => {939 .fn_proto_one => {
940 var params: [1]ast.Node.Index = undefined;940 var params: [1]Ast.Node.Index = undefined;
941 return fnProtoExpr(gz, scope, rl, tree.fnProtoOne(&params, node));941 return fnProtoExpr(gz, scope, rl, tree.fnProtoOne(&params, node));
942 },942 },
943 .fn_proto => {943 .fn_proto => {
...@@ -950,7 +950,7 @@ fn nosuspendExpr(...@@ -950,7 +950,7 @@ fn nosuspendExpr(
950 gz: *GenZir,950 gz: *GenZir,
951 scope: *Scope,951 scope: *Scope,
952 rl: ResultLoc,952 rl: ResultLoc,
953 node: ast.Node.Index,953 node: Ast.Node.Index,
954) InnerError!Zir.Inst.Ref {954) InnerError!Zir.Inst.Ref {
955 const astgen = gz.astgen;955 const astgen = gz.astgen;
956 const tree = astgen.tree;956 const tree = astgen.tree;
...@@ -971,7 +971,7 @@ fn nosuspendExpr(...@@ -971,7 +971,7 @@ fn nosuspendExpr(
971fn suspendExpr(971fn suspendExpr(
972 gz: *GenZir,972 gz: *GenZir,
973 scope: *Scope,973 scope: *Scope,
974 node: ast.Node.Index,974 node: Ast.Node.Index,
975) InnerError!Zir.Inst.Ref {975) InnerError!Zir.Inst.Ref {
976 const astgen = gz.astgen;976 const astgen = gz.astgen;
977 const gpa = astgen.gpa;977 const gpa = astgen.gpa;
...@@ -1011,7 +1011,7 @@ fn awaitExpr(...@@ -1011,7 +1011,7 @@ fn awaitExpr(
1011 gz: *GenZir,1011 gz: *GenZir,
1012 scope: *Scope,1012 scope: *Scope,
1013 rl: ResultLoc,1013 rl: ResultLoc,
1014 node: ast.Node.Index,1014 node: Ast.Node.Index,
1015) InnerError!Zir.Inst.Ref {1015) InnerError!Zir.Inst.Ref {
1016 const astgen = gz.astgen;1016 const astgen = gz.astgen;
1017 const tree = astgen.tree;1017 const tree = astgen.tree;
...@@ -1033,7 +1033,7 @@ fn resumeExpr(...@@ -1033,7 +1033,7 @@ fn resumeExpr(
1033 gz: *GenZir,1033 gz: *GenZir,
1034 scope: *Scope,1034 scope: *Scope,
1035 rl: ResultLoc,1035 rl: ResultLoc,
1036 node: ast.Node.Index,1036 node: Ast.Node.Index,
1037) InnerError!Zir.Inst.Ref {1037) InnerError!Zir.Inst.Ref {
1038 const astgen = gz.astgen;1038 const astgen = gz.astgen;
1039 const tree = astgen.tree;1039 const tree = astgen.tree;
...@@ -1048,7 +1048,7 @@ fn fnProtoExpr(...@@ -1048,7 +1048,7 @@ fn fnProtoExpr(
1048 gz: *GenZir,1048 gz: *GenZir,
1049 scope: *Scope,1049 scope: *Scope,
1050 rl: ResultLoc,1050 rl: ResultLoc,
1051 fn_proto: ast.full.FnProto,1051 fn_proto: Ast.full.FnProto,
1052) InnerError!Zir.Inst.Ref {1052) InnerError!Zir.Inst.Ref {
1053 const astgen = gz.astgen;1053 const astgen = gz.astgen;
1054 const gpa = astgen.gpa;1054 const gpa = astgen.gpa;
...@@ -1159,8 +1159,8 @@ fn arrayInitExpr(...@@ -1159,8 +1159,8 @@ fn arrayInitExpr(
1159 gz: *GenZir,1159 gz: *GenZir,
1160 scope: *Scope,1160 scope: *Scope,
1161 rl: ResultLoc,1161 rl: ResultLoc,
1162 node: ast.Node.Index,1162 node: Ast.Node.Index,
1163 array_init: ast.full.ArrayInit,1163 array_init: Ast.full.ArrayInit,
1164) InnerError!Zir.Inst.Ref {1164) InnerError!Zir.Inst.Ref {
1165 const astgen = gz.astgen;1165 const astgen = gz.astgen;
1166 const tree = astgen.tree;1166 const tree = astgen.tree;
...@@ -1179,7 +1179,7 @@ fn arrayInitExpr(...@@ -1179,7 +1179,7 @@ fn arrayInitExpr(
1179 };1179 };
11801180
1181 infer: {1181 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]) {
1183 .array_type => tree.arrayType(array_init.ast.type_expr),1183 .array_type => tree.arrayType(array_init.ast.type_expr),
1184 .array_type_sentinel => tree.arrayTypeSentinel(array_init.ast.type_expr),1184 .array_type_sentinel => tree.arrayTypeSentinel(array_init.ast.type_expr),
1185 else => break :infer,1185 else => break :infer,
...@@ -1256,8 +1256,8 @@ fn arrayInitExpr(...@@ -1256,8 +1256,8 @@ fn arrayInitExpr(
1256fn arrayInitExprRlNone(1256fn arrayInitExprRlNone(
1257 gz: *GenZir,1257 gz: *GenZir,
1258 scope: *Scope,1258 scope: *Scope,
1259 node: ast.Node.Index,1259 node: Ast.Node.Index,
1260 elements: []const ast.Node.Index,1260 elements: []const Ast.Node.Index,
1261 tag: Zir.Inst.Tag,1261 tag: Zir.Inst.Tag,
1262) InnerError!Zir.Inst.Ref {1262) InnerError!Zir.Inst.Ref {
1263 const astgen = gz.astgen;1263 const astgen = gz.astgen;
...@@ -1278,8 +1278,8 @@ fn arrayInitExprRlNone(...@@ -1278,8 +1278,8 @@ fn arrayInitExprRlNone(
1278fn arrayInitExprRlTy(1278fn arrayInitExprRlTy(
1279 gz: *GenZir,1279 gz: *GenZir,
1280 scope: *Scope,1280 scope: *Scope,
1281 node: ast.Node.Index,1281 node: Ast.Node.Index,
1282 elements: []const ast.Node.Index,1282 elements: []const Ast.Node.Index,
1283 elem_ty_inst: Zir.Inst.Ref,1283 elem_ty_inst: Zir.Inst.Ref,
1284 tag: Zir.Inst.Tag,1284 tag: Zir.Inst.Tag,
1285) InnerError!Zir.Inst.Ref {1285) InnerError!Zir.Inst.Ref {
...@@ -1304,8 +1304,8 @@ fn arrayInitExprRlTy(...@@ -1304,8 +1304,8 @@ fn arrayInitExprRlTy(
1304fn arrayInitExprRlPtr(1304fn arrayInitExprRlPtr(
1305 gz: *GenZir,1305 gz: *GenZir,
1306 scope: *Scope,1306 scope: *Scope,
1307 node: ast.Node.Index,1307 node: Ast.Node.Index,
1308 elements: []const ast.Node.Index,1308 elements: []const Ast.Node.Index,
1309 result_ptr: Zir.Inst.Ref,1309 result_ptr: Zir.Inst.Ref,
1310) InnerError!Zir.Inst.Ref {1310) InnerError!Zir.Inst.Ref {
1311 const astgen = gz.astgen;1311 const astgen = gz.astgen;
...@@ -1334,8 +1334,8 @@ fn structInitExpr(...@@ -1334,8 +1334,8 @@ fn structInitExpr(
1334 gz: *GenZir,1334 gz: *GenZir,
1335 scope: *Scope,1335 scope: *Scope,
1336 rl: ResultLoc,1336 rl: ResultLoc,
1337 node: ast.Node.Index,1337 node: Ast.Node.Index,
1338 struct_init: ast.full.StructInit,1338 struct_init: Ast.full.StructInit,
1339) InnerError!Zir.Inst.Ref {1339) InnerError!Zir.Inst.Ref {
1340 const astgen = gz.astgen;1340 const astgen = gz.astgen;
1341 const tree = astgen.tree;1341 const tree = astgen.tree;
...@@ -1347,7 +1347,7 @@ fn structInitExpr(...@@ -1347,7 +1347,7 @@ fn structInitExpr(
1347 } else array: {1347 } else array: {
1348 const node_tags = tree.nodes.items(.tag);1348 const node_tags = tree.nodes.items(.tag);
1349 const main_tokens = tree.nodes.items(.main_token);1349 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]) {
1351 .array_type => tree.arrayType(struct_init.ast.type_expr),1351 .array_type => tree.arrayType(struct_init.ast.type_expr),
1352 .array_type_sentinel => tree.arrayTypeSentinel(struct_init.ast.type_expr),1352 .array_type_sentinel => tree.arrayTypeSentinel(struct_init.ast.type_expr),
1353 else => break :array,1353 else => break :array,
...@@ -1420,8 +1420,8 @@ fn structInitExpr(...@@ -1420,8 +1420,8 @@ fn structInitExpr(
1420fn structInitExprRlNone(1420fn structInitExprRlNone(
1421 gz: *GenZir,1421 gz: *GenZir,
1422 scope: *Scope,1422 scope: *Scope,
1423 node: ast.Node.Index,1423 node: Ast.Node.Index,
1424 struct_init: ast.full.StructInit,1424 struct_init: Ast.full.StructInit,
1425 tag: Zir.Inst.Tag,1425 tag: Zir.Inst.Tag,
1426) InnerError!Zir.Inst.Ref {1426) InnerError!Zir.Inst.Ref {
1427 const astgen = gz.astgen;1427 const astgen = gz.astgen;
...@@ -1454,8 +1454,8 @@ fn structInitExprRlNone(...@@ -1454,8 +1454,8 @@ fn structInitExprRlNone(
1454fn structInitExprRlPtr(1454fn structInitExprRlPtr(
1455 gz: *GenZir,1455 gz: *GenZir,
1456 scope: *Scope,1456 scope: *Scope,
1457 node: ast.Node.Index,1457 node: Ast.Node.Index,
1458 struct_init: ast.full.StructInit,1458 struct_init: Ast.full.StructInit,
1459 result_ptr: Zir.Inst.Ref,1459 result_ptr: Zir.Inst.Ref,
1460) InnerError!Zir.Inst.Ref {1460) InnerError!Zir.Inst.Ref {
1461 const astgen = gz.astgen;1461 const astgen = gz.astgen;
...@@ -1488,8 +1488,8 @@ fn structInitExprRlPtr(...@@ -1488,8 +1488,8 @@ fn structInitExprRlPtr(
1488fn structInitExprRlTy(1488fn structInitExprRlTy(
1489 gz: *GenZir,1489 gz: *GenZir,
1490 scope: *Scope,1490 scope: *Scope,
1491 node: ast.Node.Index,1491 node: Ast.Node.Index,
1492 struct_init: ast.full.StructInit,1492 struct_init: Ast.full.StructInit,
1493 ty_inst: Zir.Inst.Ref,1493 ty_inst: Zir.Inst.Ref,
1494 tag: Zir.Inst.Tag,1494 tag: Zir.Inst.Tag,
1495) InnerError!Zir.Inst.Ref {1495) InnerError!Zir.Inst.Ref {
...@@ -1530,7 +1530,7 @@ fn comptimeExpr(...@@ -1530,7 +1530,7 @@ fn comptimeExpr(
1530 gz: *GenZir,1530 gz: *GenZir,
1531 scope: *Scope,1531 scope: *Scope,
1532 rl: ResultLoc,1532 rl: ResultLoc,
1533 node: ast.Node.Index,1533 node: Ast.Node.Index,
1534) InnerError!Zir.Inst.Ref {1534) InnerError!Zir.Inst.Ref {
1535 const prev_force_comptime = gz.force_comptime;1535 const prev_force_comptime = gz.force_comptime;
1536 gz.force_comptime = true;1536 gz.force_comptime = true;
...@@ -1546,7 +1546,7 @@ fn comptimeExprAst(...@@ -1546,7 +1546,7 @@ fn comptimeExprAst(
1546 gz: *GenZir,1546 gz: *GenZir,
1547 scope: *Scope,1547 scope: *Scope,
1548 rl: ResultLoc,1548 rl: ResultLoc,
1549 node: ast.Node.Index,1549 node: Ast.Node.Index,
1550) InnerError!Zir.Inst.Ref {1550) InnerError!Zir.Inst.Ref {
1551 const astgen = gz.astgen;1551 const astgen = gz.astgen;
1552 if (gz.force_comptime) {1552 if (gz.force_comptime) {
...@@ -1561,7 +1561,7 @@ fn comptimeExprAst(...@@ -1561,7 +1561,7 @@ fn comptimeExprAst(
1561 return result;1561 return result;
1562}1562}
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 {
1565 const astgen = parent_gz.astgen;1565 const astgen = parent_gz.astgen;
1566 const tree = astgen.tree;1566 const tree = astgen.tree;
1567 const node_datas = tree.nodes.items(.data);1567 const node_datas = tree.nodes.items(.data);
...@@ -1636,7 +1636,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn...@@ -1636,7 +1636,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn
1636 }1636 }
1637}1637}
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 {
1640 const astgen = parent_gz.astgen;1640 const astgen = parent_gz.astgen;
1641 const tree = astgen.tree;1641 const tree = astgen.tree;
1642 const node_datas = tree.nodes.items(.data);1642 const node_datas = tree.nodes.items(.data);
...@@ -1694,8 +1694,8 @@ fn blockExpr(...@@ -1694,8 +1694,8 @@ fn blockExpr(
1694 gz: *GenZir,1694 gz: *GenZir,
1695 scope: *Scope,1695 scope: *Scope,
1696 rl: ResultLoc,1696 rl: ResultLoc,
1697 block_node: ast.Node.Index,1697 block_node: Ast.Node.Index,
1698 statements: []const ast.Node.Index,1698 statements: []const Ast.Node.Index,
1699) InnerError!Zir.Inst.Ref {1699) InnerError!Zir.Inst.Ref {
1700 const tracy = trace(@src());1700 const tracy = trace(@src());
1701 defer tracy.end();1701 defer tracy.end();
...@@ -1716,7 +1716,7 @@ fn blockExpr(...@@ -1716,7 +1716,7 @@ fn blockExpr(
1716 return rvalue(gz, rl, .void_value, block_node);1716 return rvalue(gz, rl, .void_value, block_node);
1717}1717}
17181718
1719fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: ast.TokenIndex) !void {1719fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: Ast.TokenIndex) !void {
1720 // Look for the label in the scope.1720 // Look for the label in the scope.
1721 var scope = parent_scope;1721 var scope = parent_scope;
1722 while (true) {1722 while (true) {
...@@ -1752,8 +1752,8 @@ fn labeledBlockExpr(...@@ -1752,8 +1752,8 @@ fn labeledBlockExpr(
1752 gz: *GenZir,1752 gz: *GenZir,
1753 parent_scope: *Scope,1753 parent_scope: *Scope,
1754 rl: ResultLoc,1754 rl: ResultLoc,
1755 block_node: ast.Node.Index,1755 block_node: Ast.Node.Index,
1756 statements: []const ast.Node.Index,1756 statements: []const Ast.Node.Index,
1757 zir_tag: Zir.Inst.Tag,1757 zir_tag: Zir.Inst.Tag,
1758) InnerError!Zir.Inst.Ref {1758) InnerError!Zir.Inst.Ref {
1759 const tracy = trace(@src());1759 const tracy = trace(@src());
...@@ -1829,7 +1829,7 @@ fn labeledBlockExpr(...@@ -1829,7 +1829,7 @@ fn labeledBlockExpr(
1829 }1829 }
1830}1830}
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 {
1833 const astgen = gz.astgen;1833 const astgen = gz.astgen;
1834 const tree = astgen.tree;1834 const tree = astgen.tree;
1835 const node_tags = tree.nodes.items(.tag);1835 const node_tags = tree.nodes.items(.tag);
...@@ -1837,7 +1837,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod...@@ -1837,7 +1837,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod
1837 var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa);1837 var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa);
1838 defer block_arena.deinit();1838 defer block_arena.deinit();
18391839
1840 var noreturn_src_node: ast.Node.Index = 0;1840 var noreturn_src_node: Ast.Node.Index = 0;
1841 var scope = parent_scope;1841 var scope = parent_scope;
1842 for (statements) |statement| {1842 for (statements) |statement| {
1843 if (noreturn_src_node != 0) {1843 if (noreturn_src_node != 0) {
...@@ -1892,12 +1892,12 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod...@@ -1892,12 +1892,12 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod
18921892
1893/// Returns AST source node of the thing that is noreturn if the statement is definitely `noreturn`.1893/// Returns AST source node of the thing that is noreturn if the statement is definitely `noreturn`.
1894/// Otherwise returns 0.1894/// 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 {
1896 try emitDbgNode(gz, statement);1896 try emitDbgNode(gz, statement);
1897 // We need to emit an error if the result is not `noreturn` or `void`, but1897 // We need to emit an error if the result is not `noreturn` or `void`, but
1898 // we want to avoid adding the ZIR instruction if possible for performance.1898 // we want to avoid adding the ZIR instruction if possible for performance.
1899 const maybe_unused_result = try expr(gz, scope, .none, statement);1899 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;
1901 const elide_check = if (refToIndex(maybe_unused_result)) |inst| b: {1901 const elide_check = if (refToIndex(maybe_unused_result)) |inst| b: {
1902 // Note that this array becomes invalid after appending more items to it1902 // Note that this array becomes invalid after appending more items to it
1903 // in the above while loop.1903 // in the above while loop.
...@@ -2344,7 +2344,7 @@ fn checkUsed(...@@ -2344,7 +2344,7 @@ fn checkUsed(
23442344
2345fn makeDeferScope(2345fn makeDeferScope(
2346 scope: *Scope,2346 scope: *Scope,
2347 node: ast.Node.Index,2347 node: Ast.Node.Index,
2348 block_arena: *Allocator,2348 block_arena: *Allocator,
2349 scope_tag: Scope.Tag,2349 scope_tag: Scope.Tag,
2350) InnerError!*Scope {2350) InnerError!*Scope {
...@@ -2360,9 +2360,9 @@ fn makeDeferScope(...@@ -2360,9 +2360,9 @@ fn makeDeferScope(
2360fn varDecl(2360fn varDecl(
2361 gz: *GenZir,2361 gz: *GenZir,
2362 scope: *Scope,2362 scope: *Scope,
2363 node: ast.Node.Index,2363 node: Ast.Node.Index,
2364 block_arena: *Allocator,2364 block_arena: *Allocator,
2365 var_decl: ast.full.VarDecl,2365 var_decl: Ast.full.VarDecl,
2366) InnerError!*Scope {2366) InnerError!*Scope {
2367 try emitDbgNode(gz, node);2367 try emitDbgNode(gz, node);
2368 const astgen = gz.astgen;2368 const astgen = gz.astgen;
...@@ -2574,7 +2574,7 @@ fn varDecl(...@@ -2574,7 +2574,7 @@ fn varDecl(
2574 }2574 }
2575}2575}
25762576
2577fn emitDbgNode(gz: *GenZir, node: ast.Node.Index) !void {2577fn emitDbgNode(gz: *GenZir, node: Ast.Node.Index) !void {
2578 // The instruction emitted here is for debugging runtime code.2578 // The instruction emitted here is for debugging runtime code.
2579 // If the current block will be evaluated only during semantic analysis2579 // If the current block will be evaluated only during semantic analysis
2580 // then no dbg_stmt ZIR instruction is needed.2580 // then no dbg_stmt ZIR instruction is needed.
...@@ -2598,7 +2598,7 @@ fn emitDbgNode(gz: *GenZir, node: ast.Node.Index) !void {...@@ -2598,7 +2598,7 @@ fn emitDbgNode(gz: *GenZir, node: ast.Node.Index) !void {
2598 } });2598 } });
2599}2599}
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 {
2602 try emitDbgNode(gz, infix_node);2602 try emitDbgNode(gz, infix_node);
2603 const astgen = gz.astgen;2603 const astgen = gz.astgen;
2604 const tree = astgen.tree;2604 const tree = astgen.tree;
...@@ -2623,7 +2623,7 @@ fn assign(gz: *GenZir, scope: *Scope, infix_node: ast.Node.Index) InnerError!voi...@@ -2623,7 +2623,7 @@ fn assign(gz: *GenZir, scope: *Scope, infix_node: ast.Node.Index) InnerError!voi
2623fn assignOp(2623fn assignOp(
2624 gz: *GenZir,2624 gz: *GenZir,
2625 scope: *Scope,2625 scope: *Scope,
2626 infix_node: ast.Node.Index,2626 infix_node: Ast.Node.Index,
2627 op_inst_tag: Zir.Inst.Tag,2627 op_inst_tag: Zir.Inst.Tag,
2628) InnerError!void {2628) InnerError!void {
2629 try emitDbgNode(gz, infix_node);2629 try emitDbgNode(gz, infix_node);
...@@ -2646,7 +2646,7 @@ fn assignOp(...@@ -2646,7 +2646,7 @@ fn assignOp(
2646fn assignShift(2646fn assignShift(
2647 gz: *GenZir,2647 gz: *GenZir,
2648 scope: *Scope,2648 scope: *Scope,
2649 infix_node: ast.Node.Index,2649 infix_node: Ast.Node.Index,
2650 op_inst_tag: Zir.Inst.Tag,2650 op_inst_tag: Zir.Inst.Tag,
2651) InnerError!void {2651) InnerError!void {
2652 try emitDbgNode(gz, infix_node);2652 try emitDbgNode(gz, infix_node);
...@@ -2666,7 +2666,7 @@ fn assignShift(...@@ -2666,7 +2666,7 @@ fn assignShift(
2666 _ = try gz.addBin(.store, lhs_ptr, result);2666 _ = try gz.addBin(.store, lhs_ptr, result);
2667}2667}
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 {
2670 const astgen = gz.astgen;2670 const astgen = gz.astgen;
2671 const tree = astgen.tree;2671 const tree = astgen.tree;
2672 const node_datas = tree.nodes.items(.data);2672 const node_datas = tree.nodes.items(.data);
...@@ -2676,7 +2676,7 @@ fn boolNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inne...@@ -2676,7 +2676,7 @@ fn boolNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inne
2676 return rvalue(gz, rl, result, node);2676 return rvalue(gz, rl, result, node);
2677}2677}
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 {
2680 const astgen = gz.astgen;2680 const astgen = gz.astgen;
2681 const tree = astgen.tree;2681 const tree = astgen.tree;
2682 const node_datas = tree.nodes.items(.data);2682 const node_datas = tree.nodes.items(.data);
...@@ -2690,7 +2690,7 @@ fn negation(...@@ -2690,7 +2690,7 @@ fn negation(
2690 gz: *GenZir,2690 gz: *GenZir,
2691 scope: *Scope,2691 scope: *Scope,
2692 rl: ResultLoc,2692 rl: ResultLoc,
2693 node: ast.Node.Index,2693 node: Ast.Node.Index,
2694 tag: Zir.Inst.Tag,2694 tag: Zir.Inst.Tag,
2695) InnerError!Zir.Inst.Ref {2695) InnerError!Zir.Inst.Ref {
2696 const astgen = gz.astgen;2696 const astgen = gz.astgen;
...@@ -2706,8 +2706,8 @@ fn ptrType(...@@ -2706,8 +2706,8 @@ fn ptrType(
2706 gz: *GenZir,2706 gz: *GenZir,
2707 scope: *Scope,2707 scope: *Scope,
2708 rl: ResultLoc,2708 rl: ResultLoc,
2709 node: ast.Node.Index,2709 node: Ast.Node.Index,
2710 ptr_info: ast.full.PtrType,2710 ptr_info: Ast.full.PtrType,
2711) InnerError!Zir.Inst.Ref {2711) InnerError!Zir.Inst.Ref {
2712 const elem_type = try typeExpr(gz, scope, ptr_info.ast.child_type);2712 const elem_type = try typeExpr(gz, scope, ptr_info.ast.child_type);
27132713
...@@ -2788,7 +2788,7 @@ fn ptrType(...@@ -2788,7 +2788,7 @@ fn ptrType(
2788 return rvalue(gz, rl, result, node);2788 return rvalue(gz, rl, result, node);
2789}2789}
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 {
2792 const astgen = gz.astgen;2792 const astgen = gz.astgen;
2793 const tree = astgen.tree;2793 const tree = astgen.tree;
2794 const node_datas = tree.nodes.items(.data);2794 const node_datas = tree.nodes.items(.data);
...@@ -2808,13 +2808,13 @@ fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !Z...@@ -2808,13 +2808,13 @@ fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !Z
2808 return rvalue(gz, rl, result, node);2808 return rvalue(gz, rl, result, node);
2809}2809}
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 {
2812 const astgen = gz.astgen;2812 const astgen = gz.astgen;
2813 const tree = astgen.tree;2813 const tree = astgen.tree;
2814 const node_datas = tree.nodes.items(.data);2814 const node_datas = tree.nodes.items(.data);
2815 const node_tags = tree.nodes.items(.tag);2815 const node_tags = tree.nodes.items(.tag);
2816 const main_tokens = tree.nodes.items(.main_token);2816 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
2819 const len_node = node_datas[node].lhs;2819 const len_node = node_datas[node].lhs;
2820 if (node_tags[len_node] == .identifier and2820 if (node_tags[len_node] == .identifier and
...@@ -2870,9 +2870,9 @@ fn fnDecl(...@@ -2870,9 +2870,9 @@ fn fnDecl(
2870 gz: *GenZir,2870 gz: *GenZir,
2871 scope: *Scope,2871 scope: *Scope,
2872 wip_decls: *WipDecls,2872 wip_decls: *WipDecls,
2873 decl_node: ast.Node.Index,2873 decl_node: Ast.Node.Index,
2874 body_node: ast.Node.Index,2874 body_node: Ast.Node.Index,
2875 fn_proto: ast.full.FnProto,2875 fn_proto: Ast.full.FnProto,
2876) InnerError!void {2876) InnerError!void {
2877 const gpa = astgen.gpa;2877 const gpa = astgen.gpa;
2878 const tree = astgen.tree;2878 const tree = astgen.tree;
...@@ -3135,8 +3135,8 @@ fn globalVarDecl(...@@ -3135,8 +3135,8 @@ fn globalVarDecl(
3135 gz: *GenZir,3135 gz: *GenZir,
3136 scope: *Scope,3136 scope: *Scope,
3137 wip_decls: *WipDecls,3137 wip_decls: *WipDecls,
3138 node: ast.Node.Index,3138 node: Ast.Node.Index,
3139 var_decl: ast.full.VarDecl,3139 var_decl: Ast.full.VarDecl,
3140) InnerError!void {3140) InnerError!void {
3141 const gpa = astgen.gpa;3141 const gpa = astgen.gpa;
3142 const tree = astgen.tree;3142 const tree = astgen.tree;
...@@ -3279,7 +3279,7 @@ fn comptimeDecl(...@@ -3279,7 +3279,7 @@ fn comptimeDecl(
3279 gz: *GenZir,3279 gz: *GenZir,
3280 scope: *Scope,3280 scope: *Scope,
3281 wip_decls: *WipDecls,3281 wip_decls: *WipDecls,
3282 node: ast.Node.Index,3282 node: Ast.Node.Index,
3283) InnerError!void {3283) InnerError!void {
3284 const gpa = astgen.gpa;3284 const gpa = astgen.gpa;
3285 const tree = astgen.tree;3285 const tree = astgen.tree;
...@@ -3326,7 +3326,7 @@ fn usingnamespaceDecl(...@@ -3326,7 +3326,7 @@ fn usingnamespaceDecl(
3326 gz: *GenZir,3326 gz: *GenZir,
3327 scope: *Scope,3327 scope: *Scope,
3328 wip_decls: *WipDecls,3328 wip_decls: *WipDecls,
3329 node: ast.Node.Index,3329 node: Ast.Node.Index,
3330) InnerError!void {3330) InnerError!void {
3331 const gpa = astgen.gpa;3331 const gpa = astgen.gpa;
3332 const tree = astgen.tree;3332 const tree = astgen.tree;
...@@ -3377,7 +3377,7 @@ fn testDecl(...@@ -3377,7 +3377,7 @@ fn testDecl(
3377 gz: *GenZir,3377 gz: *GenZir,
3378 scope: *Scope,3378 scope: *Scope,
3379 wip_decls: *WipDecls,3379 wip_decls: *WipDecls,
3380 node: ast.Node.Index,3380 node: Ast.Node.Index,
3381) InnerError!void {3381) InnerError!void {
3382 const gpa = astgen.gpa;3382 const gpa = astgen.gpa;
3383 const tree = astgen.tree;3383 const tree = astgen.tree;
...@@ -3468,8 +3468,8 @@ fn testDecl(...@@ -3468,8 +3468,8 @@ fn testDecl(
3468fn structDeclInner(3468fn structDeclInner(
3469 gz: *GenZir,3469 gz: *GenZir,
3470 scope: *Scope,3470 scope: *Scope,
3471 node: ast.Node.Index,3471 node: Ast.Node.Index,
3472 container_decl: ast.full.ContainerDecl,3472 container_decl: Ast.full.ContainerDecl,
3473 layout: std.builtin.TypeInfo.ContainerLayout,3473 layout: std.builtin.TypeInfo.ContainerLayout,
3474) InnerError!Zir.Inst.Ref {3474) InnerError!Zir.Inst.Ref {
3475 if (container_decl.ast.members.len == 0) {3475 if (container_decl.ast.members.len == 0) {
...@@ -3537,7 +3537,7 @@ fn structDeclInner(...@@ -3537,7 +3537,7 @@ fn structDeclInner(
3537 const body = node_datas[member_node].rhs;3537 const body = node_datas[member_node].rhs;
3538 switch (node_tags[fn_proto]) {3538 switch (node_tags[fn_proto]) {
3539 .fn_proto_simple => {3539 .fn_proto_simple => {
3540 var params: [1]ast.Node.Index = undefined;3540 var params: [1]Ast.Node.Index = undefined;
3541 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {3541 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
3542 error.OutOfMemory => return error.OutOfMemory,3542 error.OutOfMemory => return error.OutOfMemory,
3543 error.AnalysisFail => {},3543 error.AnalysisFail => {},
...@@ -3552,7 +3552,7 @@ fn structDeclInner(...@@ -3552,7 +3552,7 @@ fn structDeclInner(
3552 continue;3552 continue;
3553 },3553 },
3554 .fn_proto_one => {3554 .fn_proto_one => {
3555 var params: [1]ast.Node.Index = undefined;3555 var params: [1]Ast.Node.Index = undefined;
3556 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {3556 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
3557 error.OutOfMemory => return error.OutOfMemory,3557 error.OutOfMemory => return error.OutOfMemory,
3558 error.AnalysisFail => {},3558 error.AnalysisFail => {},
...@@ -3570,7 +3570,7 @@ fn structDeclInner(...@@ -3570,7 +3570,7 @@ fn structDeclInner(
3570 }3570 }
3571 },3571 },
3572 .fn_proto_simple => {3572 .fn_proto_simple => {
3573 var params: [1]ast.Node.Index = undefined;3573 var params: [1]Ast.Node.Index = undefined;
3574 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {3574 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
3575 error.OutOfMemory => return error.OutOfMemory,3575 error.OutOfMemory => return error.OutOfMemory,
3576 error.AnalysisFail => {},3576 error.AnalysisFail => {},
...@@ -3585,7 +3585,7 @@ fn structDeclInner(...@@ -3585,7 +3585,7 @@ fn structDeclInner(
3585 continue;3585 continue;
3586 },3586 },
3587 .fn_proto_one => {3587 .fn_proto_one => {
3588 var params: [1]ast.Node.Index = undefined;3588 var params: [1]Ast.Node.Index = undefined;
3589 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {3589 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
3590 error.OutOfMemory => return error.OutOfMemory,3590 error.OutOfMemory => return error.OutOfMemory,
3591 error.AnalysisFail => {},3591 error.AnalysisFail => {},
...@@ -3750,10 +3750,10 @@ fn structDeclInner(...@@ -3750,10 +3750,10 @@ fn structDeclInner(
3750fn unionDeclInner(3750fn unionDeclInner(
3751 gz: *GenZir,3751 gz: *GenZir,
3752 scope: *Scope,3752 scope: *Scope,
3753 node: ast.Node.Index,3753 node: Ast.Node.Index,
3754 members: []const ast.Node.Index,3754 members: []const Ast.Node.Index,
3755 layout: std.builtin.TypeInfo.ContainerLayout,3755 layout: std.builtin.TypeInfo.ContainerLayout,
3756 arg_node: ast.Node.Index,3756 arg_node: Ast.Node.Index,
3757 have_auto_enum: bool,3757 have_auto_enum: bool,
3758) InnerError!Zir.Inst.Ref {3758) InnerError!Zir.Inst.Ref {
3759 const astgen = gz.astgen;3759 const astgen = gz.astgen;
...@@ -3812,7 +3812,7 @@ fn unionDeclInner(...@@ -3812,7 +3812,7 @@ fn unionDeclInner(
3812 const body = node_datas[member_node].rhs;3812 const body = node_datas[member_node].rhs;
3813 switch (node_tags[fn_proto]) {3813 switch (node_tags[fn_proto]) {
3814 .fn_proto_simple => {3814 .fn_proto_simple => {
3815 var params: [1]ast.Node.Index = undefined;3815 var params: [1]Ast.Node.Index = undefined;
3816 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {3816 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
3817 error.OutOfMemory => return error.OutOfMemory,3817 error.OutOfMemory => return error.OutOfMemory,
3818 error.AnalysisFail => {},3818 error.AnalysisFail => {},
...@@ -3827,7 +3827,7 @@ fn unionDeclInner(...@@ -3827,7 +3827,7 @@ fn unionDeclInner(
3827 continue;3827 continue;
3828 },3828 },
3829 .fn_proto_one => {3829 .fn_proto_one => {
3830 var params: [1]ast.Node.Index = undefined;3830 var params: [1]Ast.Node.Index = undefined;
3831 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {3831 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
3832 error.OutOfMemory => return error.OutOfMemory,3832 error.OutOfMemory => return error.OutOfMemory,
3833 error.AnalysisFail => {},3833 error.AnalysisFail => {},
...@@ -3845,7 +3845,7 @@ fn unionDeclInner(...@@ -3845,7 +3845,7 @@ fn unionDeclInner(
3845 }3845 }
3846 },3846 },
3847 .fn_proto_simple => {3847 .fn_proto_simple => {
3848 var params: [1]ast.Node.Index = undefined;3848 var params: [1]Ast.Node.Index = undefined;
3849 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {3849 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
3850 error.OutOfMemory => return error.OutOfMemory,3850 error.OutOfMemory => return error.OutOfMemory,
3851 error.AnalysisFail => {},3851 error.AnalysisFail => {},
...@@ -3860,7 +3860,7 @@ fn unionDeclInner(...@@ -3860,7 +3860,7 @@ fn unionDeclInner(
3860 continue;3860 continue;
3861 },3861 },
3862 .fn_proto_one => {3862 .fn_proto_one => {
3863 var params: [1]ast.Node.Index = undefined;3863 var params: [1]Ast.Node.Index = undefined;
3864 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {3864 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
3865 error.OutOfMemory => return error.OutOfMemory,3865 error.OutOfMemory => return error.OutOfMemory,
3866 error.AnalysisFail => {},3866 error.AnalysisFail => {},
...@@ -4033,8 +4033,8 @@ fn containerDecl(...@@ -4033,8 +4033,8 @@ fn containerDecl(
4033 gz: *GenZir,4033 gz: *GenZir,
4034 scope: *Scope,4034 scope: *Scope,
4035 rl: ResultLoc,4035 rl: ResultLoc,
4036 node: ast.Node.Index,4036 node: Ast.Node.Index,
4037 container_decl: ast.full.ContainerDecl,4037 container_decl: Ast.full.ContainerDecl,
4038) InnerError!Zir.Inst.Ref {4038) InnerError!Zir.Inst.Ref {
4039 const astgen = gz.astgen;4039 const astgen = gz.astgen;
4040 const gpa = astgen.gpa;4040 const gpa = astgen.gpa;
...@@ -4084,7 +4084,7 @@ fn containerDecl(...@@ -4084,7 +4084,7 @@ fn containerDecl(
4084 var values: usize = 0;4084 var values: usize = 0;
4085 var total_fields: usize = 0;4085 var total_fields: usize = 0;
4086 var decls: usize = 0;4086 var decls: usize = 0;
4087 var nonexhaustive_node: ast.Node.Index = 0;4087 var nonexhaustive_node: Ast.Node.Index = 0;
4088 for (container_decl.ast.members) |member_node| {4088 for (container_decl.ast.members) |member_node| {
4089 const member = switch (node_tags[member_node]) {4089 const member = switch (node_tags[member_node]) {
4090 .container_field_init => tree.containerFieldInit(member_node),4090 .container_field_init => tree.containerFieldInit(member_node),
...@@ -4225,7 +4225,7 @@ fn containerDecl(...@@ -4225,7 +4225,7 @@ fn containerDecl(
4225 const body = node_datas[member_node].rhs;4225 const body = node_datas[member_node].rhs;
4226 switch (node_tags[fn_proto]) {4226 switch (node_tags[fn_proto]) {
4227 .fn_proto_simple => {4227 .fn_proto_simple => {
4228 var params: [1]ast.Node.Index = undefined;4228 var params: [1]Ast.Node.Index = undefined;
4229 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {4229 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
4230 error.OutOfMemory => return error.OutOfMemory,4230 error.OutOfMemory => return error.OutOfMemory,
4231 error.AnalysisFail => {},4231 error.AnalysisFail => {},
...@@ -4240,7 +4240,7 @@ fn containerDecl(...@@ -4240,7 +4240,7 @@ fn containerDecl(
4240 continue;4240 continue;
4241 },4241 },
4242 .fn_proto_one => {4242 .fn_proto_one => {
4243 var params: [1]ast.Node.Index = undefined;4243 var params: [1]Ast.Node.Index = undefined;
4244 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {4244 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
4245 error.OutOfMemory => return error.OutOfMemory,4245 error.OutOfMemory => return error.OutOfMemory,
4246 error.AnalysisFail => {},4246 error.AnalysisFail => {},
...@@ -4258,7 +4258,7 @@ fn containerDecl(...@@ -4258,7 +4258,7 @@ fn containerDecl(
4258 }4258 }
4259 },4259 },
4260 .fn_proto_simple => {4260 .fn_proto_simple => {
4261 var params: [1]ast.Node.Index = undefined;4261 var params: [1]Ast.Node.Index = undefined;
4262 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {4262 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
4263 error.OutOfMemory => return error.OutOfMemory,4263 error.OutOfMemory => return error.OutOfMemory,
4264 error.AnalysisFail => {},4264 error.AnalysisFail => {},
...@@ -4273,7 +4273,7 @@ fn containerDecl(...@@ -4273,7 +4273,7 @@ fn containerDecl(
4273 continue;4273 continue;
4274 },4274 },
4275 .fn_proto_one => {4275 .fn_proto_one => {
4276 var params: [1]ast.Node.Index = undefined;4276 var params: [1]Ast.Node.Index = undefined;
4277 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {4277 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
4278 error.OutOfMemory => return error.OutOfMemory,4278 error.OutOfMemory => return error.OutOfMemory,
4279 error.AnalysisFail => {},4279 error.AnalysisFail => {},
...@@ -4441,7 +4441,7 @@ fn containerDecl(...@@ -4441,7 +4441,7 @@ fn containerDecl(
4441 const body = node_datas[member_node].rhs;4441 const body = node_datas[member_node].rhs;
4442 switch (node_tags[fn_proto]) {4442 switch (node_tags[fn_proto]) {
4443 .fn_proto_simple => {4443 .fn_proto_simple => {
4444 var params: [1]ast.Node.Index = undefined;4444 var params: [1]Ast.Node.Index = undefined;
4445 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {4445 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
4446 error.OutOfMemory => return error.OutOfMemory,4446 error.OutOfMemory => return error.OutOfMemory,
4447 error.AnalysisFail => {},4447 error.AnalysisFail => {},
...@@ -4456,7 +4456,7 @@ fn containerDecl(...@@ -4456,7 +4456,7 @@ fn containerDecl(
4456 continue;4456 continue;
4457 },4457 },
4458 .fn_proto_one => {4458 .fn_proto_one => {
4459 var params: [1]ast.Node.Index = undefined;4459 var params: [1]Ast.Node.Index = undefined;
4460 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {4460 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
4461 error.OutOfMemory => return error.OutOfMemory,4461 error.OutOfMemory => return error.OutOfMemory,
4462 error.AnalysisFail => {},4462 error.AnalysisFail => {},
...@@ -4474,7 +4474,7 @@ fn containerDecl(...@@ -4474,7 +4474,7 @@ fn containerDecl(
4474 }4474 }
4475 },4475 },
4476 .fn_proto_simple => {4476 .fn_proto_simple => {
4477 var params: [1]ast.Node.Index = undefined;4477 var params: [1]Ast.Node.Index = undefined;
4478 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {4478 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
4479 error.OutOfMemory => return error.OutOfMemory,4479 error.OutOfMemory => return error.OutOfMemory,
4480 error.AnalysisFail => {},4480 error.AnalysisFail => {},
...@@ -4489,7 +4489,7 @@ fn containerDecl(...@@ -4489,7 +4489,7 @@ fn containerDecl(
4489 continue;4489 continue;
4490 },4490 },
4491 .fn_proto_one => {4491 .fn_proto_one => {
4492 var params: [1]ast.Node.Index = undefined;4492 var params: [1]Ast.Node.Index = undefined;
4493 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {4493 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
4494 error.OutOfMemory => return error.OutOfMemory,4494 error.OutOfMemory => return error.OutOfMemory,
4495 error.AnalysisFail => {},4495 error.AnalysisFail => {},
...@@ -4590,7 +4590,7 @@ fn containerDecl(...@@ -4590,7 +4590,7 @@ fn containerDecl(
4590 }4590 }
4591}4591}
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 {
4594 const astgen = gz.astgen;4594 const astgen = gz.astgen;
4595 const gpa = astgen.gpa;4595 const gpa = astgen.gpa;
4596 const tree = astgen.tree;4596 const tree = astgen.tree;
...@@ -4629,8 +4629,8 @@ fn tryExpr(...@@ -4629,8 +4629,8 @@ fn tryExpr(
4629 parent_gz: *GenZir,4629 parent_gz: *GenZir,
4630 scope: *Scope,4630 scope: *Scope,
4631 rl: ResultLoc,4631 rl: ResultLoc,
4632 node: ast.Node.Index,4632 node: Ast.Node.Index,
4633 operand_node: ast.Node.Index,4633 operand_node: Ast.Node.Index,
4634) InnerError!Zir.Inst.Ref {4634) InnerError!Zir.Inst.Ref {
4635 const astgen = parent_gz.astgen;4635 const astgen = parent_gz.astgen;
46364636
...@@ -4705,13 +4705,13 @@ fn orelseCatchExpr(...@@ -4705,13 +4705,13 @@ fn orelseCatchExpr(
4705 parent_gz: *GenZir,4705 parent_gz: *GenZir,
4706 scope: *Scope,4706 scope: *Scope,
4707 rl: ResultLoc,4707 rl: ResultLoc,
4708 node: ast.Node.Index,4708 node: Ast.Node.Index,
4709 lhs: ast.Node.Index,4709 lhs: Ast.Node.Index,
4710 cond_op: Zir.Inst.Tag,4710 cond_op: Zir.Inst.Tag,
4711 unwrap_op: Zir.Inst.Tag,4711 unwrap_op: Zir.Inst.Tag,
4712 unwrap_code_op: Zir.Inst.Tag,4712 unwrap_code_op: Zir.Inst.Tag,
4713 rhs: ast.Node.Index,4713 rhs: Ast.Node.Index,
4714 payload_token: ?ast.TokenIndex,4714 payload_token: ?Ast.TokenIndex,
4715) InnerError!Zir.Inst.Ref {4715) InnerError!Zir.Inst.Ref {
4716 const astgen = parent_gz.astgen;4716 const astgen = parent_gz.astgen;
4717 const tree = astgen.tree;4717 const tree = astgen.tree;
...@@ -4796,7 +4796,7 @@ fn orelseCatchExpr(...@@ -4796,7 +4796,7 @@ fn orelseCatchExpr(
4796fn finishThenElseBlock(4796fn finishThenElseBlock(
4797 parent_gz: *GenZir,4797 parent_gz: *GenZir,
4798 rl: ResultLoc,4798 rl: ResultLoc,
4799 node: ast.Node.Index,4799 node: Ast.Node.Index,
4800 block_scope: *GenZir,4800 block_scope: *GenZir,
4801 then_scope: *GenZir,4801 then_scope: *GenZir,
4802 else_scope: *GenZir,4802 else_scope: *GenZir,
...@@ -4852,7 +4852,7 @@ fn finishThenElseBlock(...@@ -4852,7 +4852,7 @@ fn finishThenElseBlock(
4852/// tokens without allocating.4852/// tokens without allocating.
4853/// OK in theory it could do it without allocating. This implementation4853/// OK in theory it could do it without allocating. This implementation
4854/// allocates when the @"" form is used.4854/// 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 {
4856 const ident_name_1 = try astgen.identifierTokenString(token1);4856 const ident_name_1 = try astgen.identifierTokenString(token1);
4857 const ident_name_2 = try astgen.identifierTokenString(token2);4857 const ident_name_2 = try astgen.identifierTokenString(token2);
4858 return mem.eql(u8, ident_name_1, ident_name_2);4858 return mem.eql(u8, ident_name_1, ident_name_2);
...@@ -4862,7 +4862,7 @@ fn fieldAccess(...@@ -4862,7 +4862,7 @@ fn fieldAccess(
4862 gz: *GenZir,4862 gz: *GenZir,
4863 scope: *Scope,4863 scope: *Scope,
4864 rl: ResultLoc,4864 rl: ResultLoc,
4865 node: ast.Node.Index,4865 node: Ast.Node.Index,
4866) InnerError!Zir.Inst.Ref {4866) InnerError!Zir.Inst.Ref {
4867 const astgen = gz.astgen;4867 const astgen = gz.astgen;
4868 const tree = astgen.tree;4868 const tree = astgen.tree;
...@@ -4889,7 +4889,7 @@ fn arrayAccess(...@@ -4889,7 +4889,7 @@ fn arrayAccess(
4889 gz: *GenZir,4889 gz: *GenZir,
4890 scope: *Scope,4890 scope: *Scope,
4891 rl: ResultLoc,4891 rl: ResultLoc,
4892 node: ast.Node.Index,4892 node: Ast.Node.Index,
4893) InnerError!Zir.Inst.Ref {4893) InnerError!Zir.Inst.Ref {
4894 const astgen = gz.astgen;4894 const astgen = gz.astgen;
4895 const tree = astgen.tree;4895 const tree = astgen.tree;
...@@ -4912,7 +4912,7 @@ fn simpleBinOp(...@@ -4912,7 +4912,7 @@ fn simpleBinOp(
4912 gz: *GenZir,4912 gz: *GenZir,
4913 scope: *Scope,4913 scope: *Scope,
4914 rl: ResultLoc,4914 rl: ResultLoc,
4915 node: ast.Node.Index,4915 node: Ast.Node.Index,
4916 op_inst_tag: Zir.Inst.Tag,4916 op_inst_tag: Zir.Inst.Tag,
4917) InnerError!Zir.Inst.Ref {4917) InnerError!Zir.Inst.Ref {
4918 const astgen = gz.astgen;4918 const astgen = gz.astgen;
...@@ -4929,8 +4929,8 @@ fn simpleBinOp(...@@ -4929,8 +4929,8 @@ fn simpleBinOp(
4929fn simpleStrTok(4929fn simpleStrTok(
4930 gz: *GenZir,4930 gz: *GenZir,
4931 rl: ResultLoc,4931 rl: ResultLoc,
4932 ident_token: ast.TokenIndex,4932 ident_token: Ast.TokenIndex,
4933 node: ast.Node.Index,4933 node: Ast.Node.Index,
4934 op_inst_tag: Zir.Inst.Tag,4934 op_inst_tag: Zir.Inst.Tag,
4935) InnerError!Zir.Inst.Ref {4935) InnerError!Zir.Inst.Ref {
4936 const astgen = gz.astgen;4936 const astgen = gz.astgen;
...@@ -4943,7 +4943,7 @@ fn boolBinOp(...@@ -4943,7 +4943,7 @@ fn boolBinOp(
4943 gz: *GenZir,4943 gz: *GenZir,
4944 scope: *Scope,4944 scope: *Scope,
4945 rl: ResultLoc,4945 rl: ResultLoc,
4946 node: ast.Node.Index,4946 node: Ast.Node.Index,
4947 zir_tag: Zir.Inst.Tag,4947 zir_tag: Zir.Inst.Tag,
4948) InnerError!Zir.Inst.Ref {4948) InnerError!Zir.Inst.Ref {
4949 const astgen = gz.astgen;4949 const astgen = gz.astgen;
...@@ -4969,8 +4969,8 @@ fn ifExpr(...@@ -4969,8 +4969,8 @@ fn ifExpr(
4969 parent_gz: *GenZir,4969 parent_gz: *GenZir,
4970 scope: *Scope,4970 scope: *Scope,
4971 rl: ResultLoc,4971 rl: ResultLoc,
4972 node: ast.Node.Index,4972 node: Ast.Node.Index,
4973 if_full: ast.full.If,4973 if_full: Ast.full.If,
4974) InnerError!Zir.Inst.Ref {4974) InnerError!Zir.Inst.Ref {
4975 const astgen = parent_gz.astgen;4975 const astgen = parent_gz.astgen;
4976 const tree = astgen.tree;4976 const tree = astgen.tree;
...@@ -5089,7 +5089,7 @@ fn ifExpr(...@@ -5089,7 +5089,7 @@ fn ifExpr(
50895089
5090 const else_node = if_full.ast.else_expr;5090 const else_node = if_full.ast.else_expr;
5091 const else_info: struct {5091 const else_info: struct {
5092 src: ast.Node.Index,5092 src: Ast.Node.Index,
5093 result: Zir.Inst.Ref,5093 result: Zir.Inst.Ref,
5094 } = if (else_node != 0) blk: {5094 } = if (else_node != 0) blk: {
5095 block_scope.break_count += 1;5095 block_scope.break_count += 1;
...@@ -5215,8 +5215,8 @@ fn whileExpr(...@@ -5215,8 +5215,8 @@ fn whileExpr(
5215 parent_gz: *GenZir,5215 parent_gz: *GenZir,
5216 scope: *Scope,5216 scope: *Scope,
5217 rl: ResultLoc,5217 rl: ResultLoc,
5218 node: ast.Node.Index,5218 node: Ast.Node.Index,
5219 while_full: ast.full.While,5219 while_full: Ast.full.While,
5220) InnerError!Zir.Inst.Ref {5220) InnerError!Zir.Inst.Ref {
5221 const astgen = parent_gz.astgen;5221 const astgen = parent_gz.astgen;
5222 const tree = astgen.tree;5222 const tree = astgen.tree;
...@@ -5368,7 +5368,7 @@ fn whileExpr(...@@ -5368,7 +5368,7 @@ fn whileExpr(
53685368
5369 const else_node = while_full.ast.else_expr;5369 const else_node = while_full.ast.else_expr;
5370 const else_info: struct {5370 const else_info: struct {
5371 src: ast.Node.Index,5371 src: Ast.Node.Index,
5372 result: Zir.Inst.Ref,5372 result: Zir.Inst.Ref,
5373 } = if (else_node != 0) blk: {5373 } = if (else_node != 0) blk: {
5374 loop_scope.break_count += 1;5374 loop_scope.break_count += 1;
...@@ -5435,8 +5435,8 @@ fn forExpr(...@@ -5435,8 +5435,8 @@ fn forExpr(
5435 parent_gz: *GenZir,5435 parent_gz: *GenZir,
5436 scope: *Scope,5436 scope: *Scope,
5437 rl: ResultLoc,5437 rl: ResultLoc,
5438 node: ast.Node.Index,5438 node: Ast.Node.Index,
5439 for_full: ast.full.While,5439 for_full: Ast.full.While,
5440) InnerError!Zir.Inst.Ref {5440) InnerError!Zir.Inst.Ref {
5441 const astgen = parent_gz.astgen;5441 const astgen = parent_gz.astgen;
54425442
...@@ -5577,7 +5577,7 @@ fn forExpr(...@@ -5577,7 +5577,7 @@ fn forExpr(
55775577
5578 const else_node = for_full.ast.else_expr;5578 const else_node = for_full.ast.else_expr;
5579 const else_info: struct {5579 const else_info: struct {
5580 src: ast.Node.Index,5580 src: Ast.Node.Index,
5581 result: Zir.Inst.Ref,5581 result: Zir.Inst.Ref,
5582 } = if (else_node != 0) blk: {5582 } = if (else_node != 0) blk: {
5583 loop_scope.break_count += 1;5583 loop_scope.break_count += 1;
...@@ -5618,7 +5618,7 @@ fn switchExpr(...@@ -5618,7 +5618,7 @@ fn switchExpr(
5618 parent_gz: *GenZir,5618 parent_gz: *GenZir,
5619 scope: *Scope,5619 scope: *Scope,
5620 rl: ResultLoc,5620 rl: ResultLoc,
5621 switch_node: ast.Node.Index,5621 switch_node: Ast.Node.Index,
5622) InnerError!Zir.Inst.Ref {5622) InnerError!Zir.Inst.Ref {
5623 const astgen = parent_gz.astgen;5623 const astgen = parent_gz.astgen;
5624 const gpa = astgen.gpa;5624 const gpa = astgen.gpa;
...@@ -5628,7 +5628,7 @@ fn switchExpr(...@@ -5628,7 +5628,7 @@ fn switchExpr(
5628 const main_tokens = tree.nodes.items(.main_token);5628 const main_tokens = tree.nodes.items(.main_token);
5629 const token_tags = tree.tokens.items(.tag);5629 const token_tags = tree.tokens.items(.tag);
5630 const operand_node = node_datas[switch_node].lhs;5630 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);
5632 const case_nodes = tree.extra_data[extra.start..extra.end];5632 const case_nodes = tree.extra_data[extra.start..extra.end];
56335633
5634 // We perform two passes over the AST. This first pass is to collect information5634 // We perform two passes over the AST. This first pass is to collect information
...@@ -5638,9 +5638,9 @@ fn switchExpr(...@@ -5638,9 +5638,9 @@ fn switchExpr(
5638 var scalar_cases_len: u32 = 0;5638 var scalar_cases_len: u32 = 0;
5639 var multi_cases_len: u32 = 0;5639 var multi_cases_len: u32 = 0;
5640 var special_prong: Zir.SpecialProng = .none;5640 var special_prong: Zir.SpecialProng = .none;
5641 var special_node: ast.Node.Index = 0;5641 var special_node: Ast.Node.Index = 0;
5642 var else_src: ?ast.TokenIndex = null;5642 var else_src: ?Ast.TokenIndex = null;
5643 var underscore_src: ?ast.TokenIndex = null;5643 var underscore_src: ?Ast.TokenIndex = null;
5644 for (case_nodes) |case_node| {5644 for (case_nodes) |case_node| {
5645 const case = switch (node_tags[case_node]) {5645 const case = switch (node_tags[case_node]) {
5646 .switch_case_one => tree.switchCaseOne(case_node),5646 .switch_case_one => tree.switchCaseOne(case_node),
...@@ -6212,7 +6212,7 @@ fn switchExpr(...@@ -6212,7 +6212,7 @@ fn switchExpr(
6212 }6212 }
6213}6213}
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 {
6216 const astgen = gz.astgen;6216 const astgen = gz.astgen;
6217 const tree = astgen.tree;6217 const tree = astgen.tree;
6218 const node_datas = tree.nodes.items(.data);6218 const node_datas = tree.nodes.items(.data);
...@@ -6311,7 +6311,7 @@ fn identifier(...@@ -6311,7 +6311,7 @@ fn identifier(
6311 gz: *GenZir,6311 gz: *GenZir,
6312 scope: *Scope,6312 scope: *Scope,
6313 rl: ResultLoc,6313 rl: ResultLoc,
6314 ident: ast.Node.Index,6314 ident: Ast.Node.Index,
6315) InnerError!Zir.Inst.Ref {6315) InnerError!Zir.Inst.Ref {
6316 const tracy = trace(@src());6316 const tracy = trace(@src());
6317 defer tracy.end();6317 defer tracy.end();
...@@ -6363,8 +6363,8 @@ fn identifier(...@@ -6363,8 +6363,8 @@ fn identifier(
6363 // Local variables, including function parameters.6363 // Local variables, including function parameters.
6364 const name_str_index = try astgen.identAsString(ident_token);6364 const name_str_index = try astgen.identAsString(ident_token);
6365 var s = scope;6365 var s = scope;
6366 var found_already: ?ast.Node.Index = null; // we have found a decl with the same name already6366 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;6367 var hit_namespace: Ast.Node.Index = 0;
6368 while (true) switch (s.tag) {6368 while (true) switch (s.tag) {
6369 .local_val => {6369 .local_val => {
6370 const local_val = s.cast(Scope.LocalVal).?;6370 const local_val = s.cast(Scope.LocalVal).?;
...@@ -6434,7 +6434,7 @@ fn identifier(...@@ -6434,7 +6434,7 @@ fn identifier(
6434fn stringLiteral(6434fn stringLiteral(
6435 gz: *GenZir,6435 gz: *GenZir,
6436 rl: ResultLoc,6436 rl: ResultLoc,
6437 node: ast.Node.Index,6437 node: Ast.Node.Index,
6438) InnerError!Zir.Inst.Ref {6438) InnerError!Zir.Inst.Ref {
6439 const astgen = gz.astgen;6439 const astgen = gz.astgen;
6440 const tree = astgen.tree;6440 const tree = astgen.tree;
...@@ -6454,7 +6454,7 @@ fn stringLiteral(...@@ -6454,7 +6454,7 @@ fn stringLiteral(
6454fn multilineStringLiteral(6454fn multilineStringLiteral(
6455 gz: *GenZir,6455 gz: *GenZir,
6456 rl: ResultLoc,6456 rl: ResultLoc,
6457 node: ast.Node.Index,6457 node: Ast.Node.Index,
6458) InnerError!Zir.Inst.Ref {6458) InnerError!Zir.Inst.Ref {
6459 const astgen = gz.astgen;6459 const astgen = gz.astgen;
6460 const str = try astgen.strLitNodeAsString(node);6460 const str = try astgen.strLitNodeAsString(node);
...@@ -6468,7 +6468,7 @@ fn multilineStringLiteral(...@@ -6468,7 +6468,7 @@ fn multilineStringLiteral(
6468 return rvalue(gz, rl, result, node);6468 return rvalue(gz, rl, result, node);
6469}6469}
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 {
6472 const astgen = gz.astgen;6472 const astgen = gz.astgen;
6473 const tree = astgen.tree;6473 const tree = astgen.tree;
6474 const main_tokens = tree.nodes.items(.main_token);6474 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 {...@@ -6547,7 +6547,7 @@ fn charLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) !Zir.Inst.Ref {
6547 }6547 }
6548}6548}
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 {
6551 const astgen = gz.astgen;6551 const astgen = gz.astgen;
6552 const tree = astgen.tree;6552 const tree = astgen.tree;
6553 const main_tokens = tree.nodes.items(.main_token);6553 const main_tokens = tree.nodes.items(.main_token);
...@@ -6593,7 +6593,7 @@ fn integerLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) InnerError!Z...@@ -6593,7 +6593,7 @@ fn integerLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) InnerError!Z
6593 return rvalue(gz, rl, result, node);6593 return rvalue(gz, rl, result, node);
6594}6594}
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 {
6597 const astgen = gz.astgen;6597 const astgen = gz.astgen;
6598 const tree = astgen.tree;6598 const tree = astgen.tree;
6599 const main_tokens = tree.nodes.items(.main_token);6599 const main_tokens = tree.nodes.items(.main_token);
...@@ -6633,8 +6633,8 @@ fn asmExpr(...@@ -6633,8 +6633,8 @@ fn asmExpr(
6633 gz: *GenZir,6633 gz: *GenZir,
6634 scope: *Scope,6634 scope: *Scope,
6635 rl: ResultLoc,6635 rl: ResultLoc,
6636 node: ast.Node.Index,6636 node: Ast.Node.Index,
6637 full: ast.full.Asm,6637 full: Ast.full.Asm,
6638) InnerError!Zir.Inst.Ref {6638) InnerError!Zir.Inst.Ref {
6639 const astgen = gz.astgen;6639 const astgen = gz.astgen;
6640 const tree = astgen.tree;6640 const tree = astgen.tree;
...@@ -6791,9 +6791,9 @@ fn as(...@@ -6791,9 +6791,9 @@ fn as(
6791 gz: *GenZir,6791 gz: *GenZir,
6792 scope: *Scope,6792 scope: *Scope,
6793 rl: ResultLoc,6793 rl: ResultLoc,
6794 node: ast.Node.Index,6794 node: Ast.Node.Index,
6795 lhs: ast.Node.Index,6795 lhs: Ast.Node.Index,
6796 rhs: ast.Node.Index,6796 rhs: Ast.Node.Index,
6797) InnerError!Zir.Inst.Ref {6797) InnerError!Zir.Inst.Ref {
6798 const dest_type = try typeExpr(gz, scope, lhs);6798 const dest_type = try typeExpr(gz, scope, lhs);
6799 switch (rl) {6799 switch (rl) {
...@@ -6814,8 +6814,8 @@ fn unionInit(...@@ -6814,8 +6814,8 @@ fn unionInit(
6814 gz: *GenZir,6814 gz: *GenZir,
6815 scope: *Scope,6815 scope: *Scope,
6816 rl: ResultLoc,6816 rl: ResultLoc,
6817 node: ast.Node.Index,6817 node: Ast.Node.Index,
6818 params: []const ast.Node.Index,6818 params: []const Ast.Node.Index,
6819) InnerError!Zir.Inst.Ref {6819) InnerError!Zir.Inst.Ref {
6820 const union_type = try typeExpr(gz, scope, params[0]);6820 const union_type = try typeExpr(gz, scope, params[0]);
6821 const field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]);6821 const field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]);
...@@ -6840,9 +6840,9 @@ fn unionInit(...@@ -6840,9 +6840,9 @@ fn unionInit(
6840fn unionInitRlPtr(6840fn unionInitRlPtr(
6841 parent_gz: *GenZir,6841 parent_gz: *GenZir,
6842 scope: *Scope,6842 scope: *Scope,
6843 node: ast.Node.Index,6843 node: Ast.Node.Index,
6844 result_ptr: Zir.Inst.Ref,6844 result_ptr: Zir.Inst.Ref,
6845 expr_node: ast.Node.Index,6845 expr_node: Ast.Node.Index,
6846 union_type: Zir.Inst.Ref,6846 union_type: Zir.Inst.Ref,
6847 field_name: Zir.Inst.Ref,6847 field_name: Zir.Inst.Ref,
6848) InnerError!Zir.Inst.Ref {6848) InnerError!Zir.Inst.Ref {
...@@ -6859,9 +6859,9 @@ fn asRlPtr(...@@ -6859,9 +6859,9 @@ fn asRlPtr(
6859 parent_gz: *GenZir,6859 parent_gz: *GenZir,
6860 scope: *Scope,6860 scope: *Scope,
6861 rl: ResultLoc,6861 rl: ResultLoc,
6862 src_node: ast.Node.Index,6862 src_node: Ast.Node.Index,
6863 result_ptr: Zir.Inst.Ref,6863 result_ptr: Zir.Inst.Ref,
6864 operand_node: ast.Node.Index,6864 operand_node: Ast.Node.Index,
6865 dest_type: Zir.Inst.Ref,6865 dest_type: Zir.Inst.Ref,
6866) InnerError!Zir.Inst.Ref {6866) InnerError!Zir.Inst.Ref {
6867 // Detect whether this expr() call goes into rvalue() to store the result into the6867 // Detect whether this expr() call goes into rvalue() to store the result into the
...@@ -6899,9 +6899,9 @@ fn bitCast(...@@ -6899,9 +6899,9 @@ fn bitCast(
6899 gz: *GenZir,6899 gz: *GenZir,
6900 scope: *Scope,6900 scope: *Scope,
6901 rl: ResultLoc,6901 rl: ResultLoc,
6902 node: ast.Node.Index,6902 node: Ast.Node.Index,
6903 lhs: ast.Node.Index,6903 lhs: Ast.Node.Index,
6904 rhs: ast.Node.Index,6904 rhs: Ast.Node.Index,
6905) InnerError!Zir.Inst.Ref {6905) InnerError!Zir.Inst.Ref {
6906 const astgen = gz.astgen;6906 const astgen = gz.astgen;
6907 const dest_type = try typeExpr(gz, scope, lhs);6907 const dest_type = try typeExpr(gz, scope, lhs);
...@@ -6929,10 +6929,10 @@ fn bitCast(...@@ -6929,10 +6929,10 @@ fn bitCast(
6929fn bitCastRlPtr(6929fn bitCastRlPtr(
6930 gz: *GenZir,6930 gz: *GenZir,
6931 scope: *Scope,6931 scope: *Scope,
6932 node: ast.Node.Index,6932 node: Ast.Node.Index,
6933 dest_type: Zir.Inst.Ref,6933 dest_type: Zir.Inst.Ref,
6934 result_ptr: Zir.Inst.Ref,6934 result_ptr: Zir.Inst.Ref,
6935 rhs: ast.Node.Index,6935 rhs: Ast.Node.Index,
6936) InnerError!Zir.Inst.Ref {6936) InnerError!Zir.Inst.Ref {
6937 const casted_result_ptr = try gz.addPlNode(.bitcast_result_ptr, node, Zir.Inst.Bin{6937 const casted_result_ptr = try gz.addPlNode(.bitcast_result_ptr, node, Zir.Inst.Bin{
6938 .lhs = dest_type,6938 .lhs = dest_type,
...@@ -6945,8 +6945,8 @@ fn typeOf(...@@ -6945,8 +6945,8 @@ fn typeOf(
6945 gz: *GenZir,6945 gz: *GenZir,
6946 scope: *Scope,6946 scope: *Scope,
6947 rl: ResultLoc,6947 rl: ResultLoc,
6948 node: ast.Node.Index,6948 node: Ast.Node.Index,
6949 params: []const ast.Node.Index,6949 params: []const Ast.Node.Index,
6950) InnerError!Zir.Inst.Ref {6950) InnerError!Zir.Inst.Ref {
6951 if (params.len < 1) {6951 if (params.len < 1) {
6952 return gz.astgen.failNode(node, "expected at least 1 argument, found 0", .{});6952 return gz.astgen.failNode(node, "expected at least 1 argument, found 0", .{});
...@@ -6970,8 +6970,8 @@ fn builtinCall(...@@ -6970,8 +6970,8 @@ fn builtinCall(
6970 gz: *GenZir,6970 gz: *GenZir,
6971 scope: *Scope,6971 scope: *Scope,
6972 rl: ResultLoc,6972 rl: ResultLoc,
6973 node: ast.Node.Index,6973 node: Ast.Node.Index,
6974 params: []const ast.Node.Index,6974 params: []const Ast.Node.Index,
6975) InnerError!Zir.Inst.Ref {6975) InnerError!Zir.Inst.Ref {
6976 const astgen = gz.astgen;6976 const astgen = gz.astgen;
6977 const tree = astgen.tree;6977 const tree = astgen.tree;
...@@ -7463,7 +7463,7 @@ fn builtinCall(...@@ -7463,7 +7463,7 @@ fn builtinCall(
7463fn simpleNoOpVoid(7463fn simpleNoOpVoid(
7464 gz: *GenZir,7464 gz: *GenZir,
7465 rl: ResultLoc,7465 rl: ResultLoc,
7466 node: ast.Node.Index,7466 node: Ast.Node.Index,
7467 tag: Zir.Inst.Tag,7467 tag: Zir.Inst.Tag,
7468) InnerError!Zir.Inst.Ref {7468) InnerError!Zir.Inst.Ref {
7469 _ = try gz.addNode(tag, node);7469 _ = try gz.addNode(tag, node);
...@@ -7474,9 +7474,9 @@ fn hasDeclOrField(...@@ -7474,9 +7474,9 @@ fn hasDeclOrField(
7474 gz: *GenZir,7474 gz: *GenZir,
7475 scope: *Scope,7475 scope: *Scope,
7476 rl: ResultLoc,7476 rl: ResultLoc,
7477 node: ast.Node.Index,7477 node: Ast.Node.Index,
7478 lhs_node: ast.Node.Index,7478 lhs_node: Ast.Node.Index,
7479 rhs_node: ast.Node.Index,7479 rhs_node: Ast.Node.Index,
7480 tag: Zir.Inst.Tag,7480 tag: Zir.Inst.Tag,
7481) InnerError!Zir.Inst.Ref {7481) InnerError!Zir.Inst.Ref {
7482 const container_type = try typeExpr(gz, scope, lhs_node);7482 const container_type = try typeExpr(gz, scope, lhs_node);
...@@ -7492,9 +7492,9 @@ fn typeCast(...@@ -7492,9 +7492,9 @@ fn typeCast(
7492 gz: *GenZir,7492 gz: *GenZir,
7493 scope: *Scope,7493 scope: *Scope,
7494 rl: ResultLoc,7494 rl: ResultLoc,
7495 node: ast.Node.Index,7495 node: Ast.Node.Index,
7496 lhs_node: ast.Node.Index,7496 lhs_node: Ast.Node.Index,
7497 rhs_node: ast.Node.Index,7497 rhs_node: Ast.Node.Index,
7498 tag: Zir.Inst.Tag,7498 tag: Zir.Inst.Tag,
7499) InnerError!Zir.Inst.Ref {7499) InnerError!Zir.Inst.Ref {
7500 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{7500 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{
...@@ -7508,8 +7508,8 @@ fn simpleUnOpType(...@@ -7508,8 +7508,8 @@ fn simpleUnOpType(
7508 gz: *GenZir,7508 gz: *GenZir,
7509 scope: *Scope,7509 scope: *Scope,
7510 rl: ResultLoc,7510 rl: ResultLoc,
7511 node: ast.Node.Index,7511 node: Ast.Node.Index,
7512 operand_node: ast.Node.Index,7512 operand_node: Ast.Node.Index,
7513 tag: Zir.Inst.Tag,7513 tag: Zir.Inst.Tag,
7514) InnerError!Zir.Inst.Ref {7514) InnerError!Zir.Inst.Ref {
7515 const operand = try typeExpr(gz, scope, operand_node);7515 const operand = try typeExpr(gz, scope, operand_node);
...@@ -7521,9 +7521,9 @@ fn simpleUnOp(...@@ -7521,9 +7521,9 @@ fn simpleUnOp(
7521 gz: *GenZir,7521 gz: *GenZir,
7522 scope: *Scope,7522 scope: *Scope,
7523 rl: ResultLoc,7523 rl: ResultLoc,
7524 node: ast.Node.Index,7524 node: Ast.Node.Index,
7525 operand_rl: ResultLoc,7525 operand_rl: ResultLoc,
7526 operand_node: ast.Node.Index,7526 operand_node: Ast.Node.Index,
7527 tag: Zir.Inst.Tag,7527 tag: Zir.Inst.Tag,
7528) InnerError!Zir.Inst.Ref {7528) InnerError!Zir.Inst.Ref {
7529 const operand = try expr(gz, scope, operand_rl, operand_node);7529 const operand = try expr(gz, scope, operand_rl, operand_node);
...@@ -7535,8 +7535,8 @@ fn cmpxchg(...@@ -7535,8 +7535,8 @@ fn cmpxchg(
7535 gz: *GenZir,7535 gz: *GenZir,
7536 scope: *Scope,7536 scope: *Scope,
7537 rl: ResultLoc,7537 rl: ResultLoc,
7538 node: ast.Node.Index,7538 node: Ast.Node.Index,
7539 params: []const ast.Node.Index,7539 params: []const Ast.Node.Index,
7540 tag: Zir.Inst.Tag,7540 tag: Zir.Inst.Tag,
7541) InnerError!Zir.Inst.Ref {7541) InnerError!Zir.Inst.Ref {
7542 const int_type = try typeExpr(gz, scope, params[0]);7542 const int_type = try typeExpr(gz, scope, params[0]);
...@@ -7565,9 +7565,9 @@ fn bitBuiltin(...@@ -7565,9 +7565,9 @@ fn bitBuiltin(
7565 gz: *GenZir,7565 gz: *GenZir,
7566 scope: *Scope,7566 scope: *Scope,
7567 rl: ResultLoc,7567 rl: ResultLoc,
7568 node: ast.Node.Index,7568 node: Ast.Node.Index,
7569 int_type_node: ast.Node.Index,7569 int_type_node: Ast.Node.Index,
7570 operand_node: ast.Node.Index,7570 operand_node: Ast.Node.Index,
7571 tag: Zir.Inst.Tag,7571 tag: Zir.Inst.Tag,
7572) InnerError!Zir.Inst.Ref {7572) InnerError!Zir.Inst.Ref {
7573 const int_type = try typeExpr(gz, scope, int_type_node);7573 const int_type = try typeExpr(gz, scope, int_type_node);
...@@ -7580,9 +7580,9 @@ fn divBuiltin(...@@ -7580,9 +7580,9 @@ fn divBuiltin(
7580 gz: *GenZir,7580 gz: *GenZir,
7581 scope: *Scope,7581 scope: *Scope,
7582 rl: ResultLoc,7582 rl: ResultLoc,
7583 node: ast.Node.Index,7583 node: Ast.Node.Index,
7584 lhs_node: ast.Node.Index,7584 lhs_node: Ast.Node.Index,
7585 rhs_node: ast.Node.Index,7585 rhs_node: Ast.Node.Index,
7586 tag: Zir.Inst.Tag,7586 tag: Zir.Inst.Tag,
7587) InnerError!Zir.Inst.Ref {7587) InnerError!Zir.Inst.Ref {
7588 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{7588 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{
...@@ -7596,8 +7596,8 @@ fn simpleCBuiltin(...@@ -7596,8 +7596,8 @@ fn simpleCBuiltin(
7596 gz: *GenZir,7596 gz: *GenZir,
7597 scope: *Scope,7597 scope: *Scope,
7598 rl: ResultLoc,7598 rl: ResultLoc,
7599 node: ast.Node.Index,7599 node: Ast.Node.Index,
7600 operand_node: ast.Node.Index,7600 operand_node: Ast.Node.Index,
7601 tag: Zir.Inst.Extended,7601 tag: Zir.Inst.Extended,
7602) InnerError!Zir.Inst.Ref {7602) InnerError!Zir.Inst.Ref {
7603 const operand = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, operand_node);7603 const operand = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, operand_node);
...@@ -7612,9 +7612,9 @@ fn offsetOf(...@@ -7612,9 +7612,9 @@ fn offsetOf(
7612 gz: *GenZir,7612 gz: *GenZir,
7613 scope: *Scope,7613 scope: *Scope,
7614 rl: ResultLoc,7614 rl: ResultLoc,
7615 node: ast.Node.Index,7615 node: Ast.Node.Index,
7616 lhs_node: ast.Node.Index,7616 lhs_node: Ast.Node.Index,
7617 rhs_node: ast.Node.Index,7617 rhs_node: Ast.Node.Index,
7618 tag: Zir.Inst.Tag,7618 tag: Zir.Inst.Tag,
7619) InnerError!Zir.Inst.Ref {7619) InnerError!Zir.Inst.Ref {
7620 const type_inst = try typeExpr(gz, scope, lhs_node);7620 const type_inst = try typeExpr(gz, scope, lhs_node);
...@@ -7630,9 +7630,9 @@ fn shiftOp(...@@ -7630,9 +7630,9 @@ fn shiftOp(
7630 gz: *GenZir,7630 gz: *GenZir,
7631 scope: *Scope,7631 scope: *Scope,
7632 rl: ResultLoc,7632 rl: ResultLoc,
7633 node: ast.Node.Index,7633 node: Ast.Node.Index,
7634 lhs_node: ast.Node.Index,7634 lhs_node: Ast.Node.Index,
7635 rhs_node: ast.Node.Index,7635 rhs_node: Ast.Node.Index,
7636 tag: Zir.Inst.Tag,7636 tag: Zir.Inst.Tag,
7637) InnerError!Zir.Inst.Ref {7637) InnerError!Zir.Inst.Ref {
7638 const lhs = try expr(gz, scope, .none, lhs_node);7638 const lhs = try expr(gz, scope, .none, lhs_node);
...@@ -7649,8 +7649,8 @@ fn cImport(...@@ -7649,8 +7649,8 @@ fn cImport(
7649 gz: *GenZir,7649 gz: *GenZir,
7650 scope: *Scope,7650 scope: *Scope,
7651 rl: ResultLoc,7651 rl: ResultLoc,
7652 node: ast.Node.Index,7652 node: Ast.Node.Index,
7653 body_node: ast.Node.Index,7653 body_node: Ast.Node.Index,
7654) InnerError!Zir.Inst.Ref {7654) InnerError!Zir.Inst.Ref {
7655 const astgen = gz.astgen;7655 const astgen = gz.astgen;
7656 const gpa = astgen.gpa;7656 const gpa = astgen.gpa;
...@@ -7674,8 +7674,8 @@ fn overflowArithmetic(...@@ -7674,8 +7674,8 @@ fn overflowArithmetic(
7674 gz: *GenZir,7674 gz: *GenZir,
7675 scope: *Scope,7675 scope: *Scope,
7676 rl: ResultLoc,7676 rl: ResultLoc,
7677 node: ast.Node.Index,7677 node: Ast.Node.Index,
7678 params: []const ast.Node.Index,7678 params: []const Ast.Node.Index,
7679 tag: Zir.Inst.Extended,7679 tag: Zir.Inst.Extended,
7680) InnerError!Zir.Inst.Ref {7680) InnerError!Zir.Inst.Ref {
7681 const int_type = try typeExpr(gz, scope, params[0]);7681 const int_type = try typeExpr(gz, scope, params[0]);
...@@ -7722,8 +7722,8 @@ fn callExpr(...@@ -7722,8 +7722,8 @@ fn callExpr(
7722 gz: *GenZir,7722 gz: *GenZir,
7723 scope: *Scope,7723 scope: *Scope,
7724 rl: ResultLoc,7724 rl: ResultLoc,
7725 node: ast.Node.Index,7725 node: Ast.Node.Index,
7726 call: ast.full.Call,7726 call: Ast.full.Call,
7727) InnerError!Zir.Inst.Ref {7727) InnerError!Zir.Inst.Ref {
7728 const astgen = gz.astgen;7728 const astgen = gz.astgen;
7729 const lhs = try expr(gz, scope, .none, call.ast.fn_expr);7729 const lhs = try expr(gz, scope, .none, call.ast.fn_expr);
...@@ -7812,7 +7812,7 @@ pub const simple_types = std.ComptimeStringMap(Zir.Inst.Ref, .{...@@ -7812,7 +7812,7 @@ pub const simple_types = std.ComptimeStringMap(Zir.Inst.Ref, .{
7812 .{ "void", .void_type },7812 .{ "void", .void_type },
7813});7813});
78147814
7815fn nodeMayNeedMemoryLocation(tree: *const ast.Tree, start_node: ast.Node.Index) bool {7815fn nodeMayNeedMemoryLocation(tree: *const Ast, start_node: Ast.Node.Index) bool {
7816 const node_tags = tree.nodes.items(.tag);7816 const node_tags = tree.nodes.items(.tag);
7817 const node_datas = tree.nodes.items(.data);7817 const node_datas = tree.nodes.items(.data);
7818 const main_tokens = tree.nodes.items(.main_token);7818 const main_tokens = tree.nodes.items(.main_token);
...@@ -8021,7 +8021,7 @@ fn nodeMayNeedMemoryLocation(tree: *const ast.Tree, start_node: ast.Node.Index)...@@ -8021,7 +8021,7 @@ fn nodeMayNeedMemoryLocation(tree: *const ast.Tree, start_node: ast.Node.Index)
8021 }8021 }
8022}8022}
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 } {
8025 const node_tags = tree.nodes.items(.tag);8025 const node_tags = tree.nodes.items(.tag);
8026 const node_datas = tree.nodes.items(.data);8026 const node_datas = tree.nodes.items(.data);
8027 const main_tokens = tree.nodes.items(.main_token);8027 const main_tokens = tree.nodes.items(.main_token);
...@@ -8230,7 +8230,7 @@ fn nodeMayEvalToError(tree: *const ast.Tree, start_node: ast.Node.Index) enum {...@@ -8230,7 +8230,7 @@ fn nodeMayEvalToError(tree: *const ast.Tree, start_node: ast.Node.Index) enum {
8230 }8230 }
8231}8231}
82328232
8233fn nodeImpliesRuntimeBits(tree: *const ast.Tree, start_node: ast.Node.Index) bool {8233fn nodeImpliesRuntimeBits(tree: *const Ast, start_node: Ast.Node.Index) bool {
8234 const node_tags = tree.nodes.items(.tag);8234 const node_tags = tree.nodes.items(.tag);
8235 const node_datas = tree.nodes.items(.data);8235 const node_datas = tree.nodes.items(.data);
82368236
...@@ -8417,7 +8417,7 @@ fn rvalue(...@@ -8417,7 +8417,7 @@ fn rvalue(
8417 gz: *GenZir,8417 gz: *GenZir,
8418 rl: ResultLoc,8418 rl: ResultLoc,
8419 result: Zir.Inst.Ref,8419 result: Zir.Inst.Ref,
8420 src_node: ast.Node.Index,8420 src_node: Ast.Node.Index,
8421) InnerError!Zir.Inst.Ref {8421) InnerError!Zir.Inst.Ref {
8422 if (gz.endsWithNoReturn()) return result;8422 if (gz.endsWithNoReturn()) return result;
8423 switch (rl) {8423 switch (rl) {
...@@ -8522,7 +8522,7 @@ fn rvalue(...@@ -8522,7 +8522,7 @@ fn rvalue(
8522/// and allocates the result within `astgen.arena`.8522/// and allocates the result within `astgen.arena`.
8523/// Otherwise, returns a reference to the source code bytes directly.8523/// Otherwise, returns a reference to the source code bytes directly.
8524/// See also `appendIdentStr` and `parseStrLit`.8524/// 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 {
8526 const tree = astgen.tree;8526 const tree = astgen.tree;
8527 const token_tags = tree.tokens.items(.tag);8527 const token_tags = tree.tokens.items(.tag);
8528 assert(token_tags[token] == .identifier);8528 assert(token_tags[token] == .identifier);
...@@ -8542,7 +8542,7 @@ fn identifierTokenString(astgen: *AstGen, token: ast.TokenIndex) InnerError![]co...@@ -8542,7 +8542,7 @@ fn identifierTokenString(astgen: *AstGen, token: ast.TokenIndex) InnerError![]co
8542/// See also `identifierTokenString` and `parseStrLit`.8542/// See also `identifierTokenString` and `parseStrLit`.
8543fn appendIdentStr(8543fn appendIdentStr(
8544 astgen: *AstGen,8544 astgen: *AstGen,
8545 token: ast.TokenIndex,8545 token: Ast.TokenIndex,
8546 buf: *ArrayListUnmanaged(u8),8546 buf: *ArrayListUnmanaged(u8),
8547) InnerError!void {8547) InnerError!void {
8548 const tree = astgen.tree;8548 const tree = astgen.tree;
...@@ -8559,7 +8559,7 @@ fn appendIdentStr(...@@ -8559,7 +8559,7 @@ fn appendIdentStr(
8559/// Appends the result to `buf`.8559/// Appends the result to `buf`.
8560fn parseStrLit(8560fn parseStrLit(
8561 astgen: *AstGen,8561 astgen: *AstGen,
8562 token: ast.TokenIndex,8562 token: Ast.TokenIndex,
8563 buf: *ArrayListUnmanaged(u8),8563 buf: *ArrayListUnmanaged(u8),
8564 bytes: []const u8,8564 bytes: []const u8,
8565 offset: u32,8565 offset: u32,
...@@ -8623,7 +8623,7 @@ fn parseStrLit(...@@ -8623,7 +8623,7 @@ fn parseStrLit(
86238623
8624fn failNode(8624fn failNode(
8625 astgen: *AstGen,8625 astgen: *AstGen,
8626 node: ast.Node.Index,8626 node: Ast.Node.Index,
8627 comptime format: []const u8,8627 comptime format: []const u8,
8628 args: anytype,8628 args: anytype,
8629) InnerError {8629) InnerError {
...@@ -8632,7 +8632,7 @@ fn failNode(...@@ -8632,7 +8632,7 @@ fn failNode(
86328632
8633fn failNodeNotes(8633fn failNodeNotes(
8634 astgen: *AstGen,8634 astgen: *AstGen,
8635 node: ast.Node.Index,8635 node: Ast.Node.Index,
8636 comptime format: []const u8,8636 comptime format: []const u8,
8637 args: anytype,8637 args: anytype,
8638 notes: []const u32,8638 notes: []const u32,
...@@ -8664,7 +8664,7 @@ fn failNodeNotes(...@@ -8664,7 +8664,7 @@ fn failNodeNotes(
86648664
8665fn failTok(8665fn failTok(
8666 astgen: *AstGen,8666 astgen: *AstGen,
8667 token: ast.TokenIndex,8667 token: Ast.TokenIndex,
8668 comptime format: []const u8,8668 comptime format: []const u8,
8669 args: anytype,8669 args: anytype,
8670) InnerError {8670) InnerError {
...@@ -8673,7 +8673,7 @@ fn failTok(...@@ -8673,7 +8673,7 @@ fn failTok(
86738673
8674fn failTokNotes(8674fn failTokNotes(
8675 astgen: *AstGen,8675 astgen: *AstGen,
8676 token: ast.TokenIndex,8676 token: Ast.TokenIndex,
8677 comptime format: []const u8,8677 comptime format: []const u8,
8678 args: anytype,8678 args: anytype,
8679 notes: []const u32,8679 notes: []const u32,
...@@ -8706,7 +8706,7 @@ fn failTokNotes(...@@ -8706,7 +8706,7 @@ fn failTokNotes(
8706/// Same as `fail`, except given an absolute byte offset.8706/// Same as `fail`, except given an absolute byte offset.
8707fn failOff(8707fn failOff(
8708 astgen: *AstGen,8708 astgen: *AstGen,
8709 token: ast.TokenIndex,8709 token: Ast.TokenIndex,
8710 byte_offset: u32,8710 byte_offset: u32,
8711 comptime format: []const u8,8711 comptime format: []const u8,
8712 args: anytype,8712 args: anytype,
...@@ -8731,7 +8731,7 @@ fn failOff(...@@ -8731,7 +8731,7 @@ fn failOff(
87318731
8732fn errNoteTok(8732fn errNoteTok(
8733 astgen: *AstGen,8733 astgen: *AstGen,
8734 token: ast.TokenIndex,8734 token: Ast.TokenIndex,
8735 comptime format: []const u8,8735 comptime format: []const u8,
8736 args: anytype,8736 args: anytype,
8737) Allocator.Error!u32 {8737) Allocator.Error!u32 {
...@@ -8754,7 +8754,7 @@ fn errNoteTok(...@@ -8754,7 +8754,7 @@ fn errNoteTok(
87548754
8755fn errNoteNode(8755fn errNoteNode(
8756 astgen: *AstGen,8756 astgen: *AstGen,
8757 node: ast.Node.Index,8757 node: Ast.Node.Index,
8758 comptime format: []const u8,8758 comptime format: []const u8,
8759 args: anytype,8759 args: anytype,
8760) Allocator.Error!u32 {8760) Allocator.Error!u32 {
...@@ -8775,7 +8775,7 @@ fn errNoteNode(...@@ -8775,7 +8775,7 @@ fn errNoteNode(
8775 });8775 });
8776}8776}
87778777
8778fn identAsString(astgen: *AstGen, ident_token: ast.TokenIndex) !u32 {8778fn identAsString(astgen: *AstGen, ident_token: Ast.TokenIndex) !u32 {
8779 const gpa = astgen.gpa;8779 const gpa = astgen.gpa;
8780 const string_bytes = &astgen.string_bytes;8780 const string_bytes = &astgen.string_bytes;
8781 const str_index = @intCast(u32, string_bytes.items.len);8781 const str_index = @intCast(u32, string_bytes.items.len);
...@@ -8798,7 +8798,7 @@ fn identAsString(astgen: *AstGen, ident_token: ast.TokenIndex) !u32 {...@@ -8798,7 +8798,7 @@ fn identAsString(astgen: *AstGen, ident_token: ast.TokenIndex) !u32 {
87988798
8799const IndexSlice = struct { index: u32, len: u32 };8799const 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 {
8802 const gpa = astgen.gpa;8802 const gpa = astgen.gpa;
8803 const string_bytes = &astgen.string_bytes;8803 const string_bytes = &astgen.string_bytes;
8804 const str_index = @intCast(u32, string_bytes.items.len);8804 const str_index = @intCast(u32, string_bytes.items.len);
...@@ -8829,7 +8829,7 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: ast.TokenIndex) !IndexSlice {...@@ -8829,7 +8829,7 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: ast.TokenIndex) !IndexSlice {
8829 }8829 }
8830}8830}
88318831
8832fn strLitNodeAsString(astgen: *AstGen, node: ast.Node.Index) !IndexSlice {8832fn strLitNodeAsString(astgen: *AstGen, node: Ast.Node.Index) !IndexSlice {
8833 const tree = astgen.tree;8833 const tree = astgen.tree;
8834 const node_datas = tree.nodes.items(.data);8834 const node_datas = tree.nodes.items(.data);
88358835
...@@ -8864,7 +8864,7 @@ fn strLitNodeAsString(astgen: *AstGen, node: ast.Node.Index) !IndexSlice {...@@ -8864,7 +8864,7 @@ fn strLitNodeAsString(astgen: *AstGen, node: ast.Node.Index) !IndexSlice {
8864 };8864 };
8865}8865}
88668866
8867fn testNameString(astgen: *AstGen, str_lit_token: ast.TokenIndex) !u32 {8867fn testNameString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !u32 {
8868 const gpa = astgen.gpa;8868 const gpa = astgen.gpa;
8869 const string_bytes = &astgen.string_bytes;8869 const string_bytes = &astgen.string_bytes;
8870 const str_index = @intCast(u32, string_bytes.items.len);8870 const str_index = @intCast(u32, string_bytes.items.len);
...@@ -8921,7 +8921,7 @@ const Scope = struct {...@@ -8921,7 +8921,7 @@ const Scope = struct {
8921 gen_zir: *GenZir,8921 gen_zir: *GenZir,
8922 inst: Zir.Inst.Ref,8922 inst: Zir.Inst.Ref,
8923 /// Source location of the corresponding variable declaration.8923 /// Source location of the corresponding variable declaration.
8924 token_src: ast.TokenIndex,8924 token_src: Ast.TokenIndex,
8925 /// String table index.8925 /// String table index.
8926 name: u32,8926 name: u32,
8927 id_cat: IdCat,8927 id_cat: IdCat,
...@@ -8940,7 +8940,7 @@ const Scope = struct {...@@ -8940,7 +8940,7 @@ const Scope = struct {
8940 gen_zir: *GenZir,8940 gen_zir: *GenZir,
8941 ptr: Zir.Inst.Ref,8941 ptr: Zir.Inst.Ref,
8942 /// Source location of the corresponding variable declaration.8942 /// Source location of the corresponding variable declaration.
8943 token_src: ast.TokenIndex,8943 token_src: Ast.TokenIndex,
8944 /// String table index.8944 /// String table index.
8945 name: u32,8945 name: u32,
8946 id_cat: IdCat,8946 id_cat: IdCat,
...@@ -8955,7 +8955,7 @@ const Scope = struct {...@@ -8955,7 +8955,7 @@ const Scope = struct {
8955 base: Scope,8955 base: Scope,
8956 /// Parents can be: `LocalVal`, `LocalPtr`, `GenZir`, `Defer`.8956 /// Parents can be: `LocalVal`, `LocalPtr`, `GenZir`, `Defer`.
8957 parent: *Scope,8957 parent: *Scope,
8958 defer_node: ast.Node.Index,8958 defer_node: Ast.Node.Index,
8959 };8959 };
89608960
8961 /// Represents a global scope that has any number of declarations in it.8961 /// Represents a global scope that has any number of declarations in it.
...@@ -8967,8 +8967,8 @@ const Scope = struct {...@@ -8967,8 +8967,8 @@ const Scope = struct {
8967 parent: *Scope,8967 parent: *Scope,
8968 /// Maps string table index to the source location of declaration,8968 /// Maps string table index to the source location of declaration,
8969 /// for the purposes of reporting name shadowing compile errors.8969 /// for the purposes of reporting name shadowing compile errors.
8970 decls: std.AutoHashMapUnmanaged(u32, ast.Node.Index) = .{},8970 decls: std.AutoHashMapUnmanaged(u32, Ast.Node.Index) = .{},
8971 node: ast.Node.Index,8971 node: Ast.Node.Index,
8972 };8972 };
89738973
8974 const Top = struct {8974 const Top = struct {
...@@ -8987,7 +8987,7 @@ const GenZir = struct {...@@ -8987,7 +8987,7 @@ const GenZir = struct {
8987 /// How decls created in this scope should be named.8987 /// How decls created in this scope should be named.
8988 anon_name_strategy: Zir.Inst.NameStrategy = .anon,8988 anon_name_strategy: Zir.Inst.NameStrategy = .anon,
8989 /// The containing decl AST node.8989 /// The containing decl AST node.
8990 decl_node_index: ast.Node.Index,8990 decl_node_index: Ast.Node.Index,
8991 /// The containing decl line index, absolute.8991 /// The containing decl line index, absolute.
8992 decl_line: u32,8992 decl_line: u32,
8993 parent: *Scope,8993 parent: *Scope,
...@@ -9022,8 +9022,8 @@ const GenZir = struct {...@@ -9022,8 +9022,8 @@ const GenZir = struct {
9022 /// a result location pointer.9022 /// a result location pointer.
9023 labeled_store_to_block_ptr_list: ArrayListUnmanaged(Zir.Inst.Index) = .{},9023 labeled_store_to_block_ptr_list: ArrayListUnmanaged(Zir.Inst.Index) = .{},
90249024
9025 suspend_node: ast.Node.Index = 0,9025 suspend_node: Ast.Node.Index = 0,
9026 nosuspend_node: ast.Node.Index = 0,9026 nosuspend_node: Ast.Node.Index = 0,
90279027
9028 fn makeSubBlock(gz: *GenZir, scope: *Scope) GenZir {9028 fn makeSubBlock(gz: *GenZir, scope: *Scope) GenZir {
9029 return .{9029 return .{
...@@ -9039,7 +9039,7 @@ const GenZir = struct {...@@ -9039,7 +9039,7 @@ const GenZir = struct {
9039 }9039 }
90409040
9041 const Label = struct {9041 const Label = struct {
9042 token: ast.TokenIndex,9042 token: Ast.TokenIndex,
9043 block_inst: Zir.Inst.Index,9043 block_inst: Zir.Inst.Index,
9044 used: bool = false,9044 used: bool = false,
9045 };9045 };
...@@ -9060,7 +9060,7 @@ const GenZir = struct {...@@ -9060,7 +9060,7 @@ const GenZir = struct {
9060 return false;9060 return false;
9061 }9061 }
90629062
9063 fn calcLine(gz: GenZir, node: ast.Node.Index) u32 {9063 fn calcLine(gz: GenZir, node: Ast.Node.Index) u32 {
9064 const astgen = gz.astgen;9064 const astgen = gz.astgen;
9065 const tree = astgen.tree;9065 const tree = astgen.tree;
9066 const source = tree.source;9066 const source = tree.source;
...@@ -9072,15 +9072,15 @@ const GenZir = struct {...@@ -9072,15 +9072,15 @@ const GenZir = struct {
9072 return @intCast(u32, gz.decl_line + astgen.source_line);9072 return @intCast(u32, gz.decl_line + astgen.source_line);
9073 }9073 }
90749074
9075 fn nodeIndexToRelative(gz: GenZir, node_index: ast.Node.Index) i32 {9075 fn nodeIndexToRelative(gz: GenZir, node_index: Ast.Node.Index) i32 {
9076 return @bitCast(i32, node_index) - @bitCast(i32, gz.decl_node_index);9076 return @bitCast(i32, node_index) - @bitCast(i32, gz.decl_node_index);
9077 }9077 }
90789078
9079 fn tokenIndexToRelative(gz: GenZir, token: ast.TokenIndex) u32 {9079 fn tokenIndexToRelative(gz: GenZir, token: Ast.TokenIndex) u32 {
9080 return token - gz.srcToken();9080 return token - gz.srcToken();
9081 }9081 }
90829082
9083 fn srcToken(gz: GenZir) ast.TokenIndex {9083 fn srcToken(gz: GenZir) Ast.TokenIndex {
9084 return gz.astgen.tree.firstToken(gz.decl_node_index);9084 return gz.astgen.tree.firstToken(gz.decl_node_index);
9085 }9085 }
90869086
...@@ -9165,7 +9165,7 @@ const GenZir = struct {...@@ -9165,7 +9165,7 @@ const GenZir = struct {
9165 }9165 }
91669166
9167 fn addFunc(gz: *GenZir, args: struct {9167 fn addFunc(gz: *GenZir, args: struct {
9168 src_node: ast.Node.Index,9168 src_node: Ast.Node.Index,
9169 body: []const Zir.Inst.Index,9169 body: []const Zir.Inst.Index,
9170 param_block: Zir.Inst.Index,9170 param_block: Zir.Inst.Index,
9171 ret_ty: []const Zir.Inst.Index,9171 ret_ty: []const Zir.Inst.Index,
...@@ -9358,7 +9358,7 @@ const GenZir = struct {...@@ -9358,7 +9358,7 @@ const GenZir = struct {
9358 callee: Zir.Inst.Ref,9358 callee: Zir.Inst.Ref,
9359 args: []const Zir.Inst.Ref,9359 args: []const Zir.Inst.Ref,
9360 /// Absolute node index. This function does the conversion to offset from Decl.9360 /// Absolute node index. This function does the conversion to offset from Decl.
9361 src_node: ast.Node.Index,9361 src_node: Ast.Node.Index,
9362 ) !Zir.Inst.Ref {9362 ) !Zir.Inst.Ref {
9363 assert(callee != .none);9363 assert(callee != .none);
9364 assert(src_node != 0);9364 assert(src_node != 0);
...@@ -9449,7 +9449,7 @@ const GenZir = struct {...@@ -9449,7 +9449,7 @@ const GenZir = struct {
9449 tag: Zir.Inst.Tag,9449 tag: Zir.Inst.Tag,
9450 operand: Zir.Inst.Ref,9450 operand: Zir.Inst.Ref,
9451 /// Absolute node index. This function does the conversion to offset from Decl.9451 /// Absolute node index. This function does the conversion to offset from Decl.
9452 src_node: ast.Node.Index,9452 src_node: Ast.Node.Index,
9453 ) !Zir.Inst.Ref {9453 ) !Zir.Inst.Ref {
9454 assert(operand != .none);9454 assert(operand != .none);
9455 return gz.add(.{9455 return gz.add(.{
...@@ -9465,7 +9465,7 @@ const GenZir = struct {...@@ -9465,7 +9465,7 @@ const GenZir = struct {
9465 gz: *GenZir,9465 gz: *GenZir,
9466 tag: Zir.Inst.Tag,9466 tag: Zir.Inst.Tag,
9467 /// Absolute node index. This function does the conversion to offset from Decl.9467 /// Absolute node index. This function does the conversion to offset from Decl.
9468 src_node: ast.Node.Index,9468 src_node: Ast.Node.Index,
9469 extra: anytype,9469 extra: anytype,
9470 ) !Zir.Inst.Ref {9470 ) !Zir.Inst.Ref {
9471 const gpa = gz.astgen.gpa;9471 const gpa = gz.astgen.gpa;
...@@ -9489,7 +9489,7 @@ const GenZir = struct {...@@ -9489,7 +9489,7 @@ const GenZir = struct {
9489 gz: *GenZir,9489 gz: *GenZir,
9490 tag: Zir.Inst.Tag,9490 tag: Zir.Inst.Tag,
9491 /// Absolute token index. This function does the conversion to Decl offset.9491 /// Absolute token index. This function does the conversion to Decl offset.
9492 abs_tok_index: ast.TokenIndex,9492 abs_tok_index: Ast.TokenIndex,
9493 name: u32,9493 name: u32,
9494 body: []const u32,9494 body: []const u32,
9495 ) !Zir.Inst.Index {9495 ) !Zir.Inst.Index {
...@@ -9544,7 +9544,7 @@ const GenZir = struct {...@@ -9544,7 +9544,7 @@ const GenZir = struct {
9544 fn addExtendedMultiOp(9544 fn addExtendedMultiOp(
9545 gz: *GenZir,9545 gz: *GenZir,
9546 opcode: Zir.Inst.Extended,9546 opcode: Zir.Inst.Extended,
9547 node: ast.Node.Index,9547 node: Ast.Node.Index,
9548 operands: []const Zir.Inst.Ref,9548 operands: []const Zir.Inst.Ref,
9549 ) !Zir.Inst.Ref {9549 ) !Zir.Inst.Ref {
9550 const astgen = gz.astgen;9550 const astgen = gz.astgen;
...@@ -9605,7 +9605,7 @@ const GenZir = struct {...@@ -9605,7 +9605,7 @@ const GenZir = struct {
9605 tag: Zir.Inst.Tag,9605 tag: Zir.Inst.Tag,
9606 operand: Zir.Inst.Ref,9606 operand: Zir.Inst.Ref,
9607 /// Absolute token index. This function does the conversion to Decl offset.9607 /// Absolute token index. This function does the conversion to Decl offset.
9608 abs_tok_index: ast.TokenIndex,9608 abs_tok_index: Ast.TokenIndex,
9609 ) !Zir.Inst.Ref {9609 ) !Zir.Inst.Ref {
9610 assert(operand != .none);9610 assert(operand != .none);
9611 return gz.add(.{9611 return gz.add(.{
...@@ -9622,7 +9622,7 @@ const GenZir = struct {...@@ -9622,7 +9622,7 @@ const GenZir = struct {
9622 tag: Zir.Inst.Tag,9622 tag: Zir.Inst.Tag,
9623 str_index: u32,9623 str_index: u32,
9624 /// Absolute token index. This function does the conversion to Decl offset.9624 /// Absolute token index. This function does the conversion to Decl offset.
9625 abs_tok_index: ast.TokenIndex,9625 abs_tok_index: Ast.TokenIndex,
9626 ) !Zir.Inst.Ref {9626 ) !Zir.Inst.Ref {
9627 return gz.add(.{9627 return gz.add(.{
9628 .tag = tag,9628 .tag = tag,
...@@ -9669,7 +9669,7 @@ const GenZir = struct {...@@ -9669,7 +9669,7 @@ const GenZir = struct {
9669 gz: *GenZir,9669 gz: *GenZir,
9670 tag: Zir.Inst.Tag,9670 tag: Zir.Inst.Tag,
9671 decl_index: u32,9671 decl_index: u32,
9672 src_node: ast.Node.Index,9672 src_node: Ast.Node.Index,
9673 ) !Zir.Inst.Ref {9673 ) !Zir.Inst.Ref {
9674 return gz.add(.{9674 return gz.add(.{
9675 .tag = tag,9675 .tag = tag,
...@@ -9684,7 +9684,7 @@ const GenZir = struct {...@@ -9684,7 +9684,7 @@ const GenZir = struct {
9684 gz: *GenZir,9684 gz: *GenZir,
9685 tag: Zir.Inst.Tag,9685 tag: Zir.Inst.Tag,
9686 /// Absolute node index. This function does the conversion to offset from Decl.9686 /// Absolute node index. This function does the conversion to offset from Decl.
9687 src_node: ast.Node.Index,9687 src_node: Ast.Node.Index,
9688 ) !Zir.Inst.Ref {9688 ) !Zir.Inst.Ref {
9689 return gz.add(.{9689 return gz.add(.{
9690 .tag = tag,9690 .tag = tag,
...@@ -9696,7 +9696,7 @@ const GenZir = struct {...@@ -9696,7 +9696,7 @@ const GenZir = struct {
9696 gz: *GenZir,9696 gz: *GenZir,
9697 opcode: Zir.Inst.Extended,9697 opcode: Zir.Inst.Extended,
9698 /// Absolute node index. This function does the conversion to offset from Decl.9698 /// Absolute node index. This function does the conversion to offset from Decl.
9699 src_node: ast.Node.Index,9699 src_node: Ast.Node.Index,
9700 ) !Zir.Inst.Ref {9700 ) !Zir.Inst.Ref {
9701 return gz.add(.{9701 return gz.add(.{
9702 .tag = .extended,9702 .tag = .extended,
...@@ -9712,7 +9712,7 @@ const GenZir = struct {...@@ -9712,7 +9712,7 @@ const GenZir = struct {
9712 gz: *GenZir,9712 gz: *GenZir,
9713 args: struct {9713 args: struct {
9714 /// Absolute node index. This function does the conversion to offset from Decl.9714 /// Absolute node index. This function does the conversion to offset from Decl.
9715 node: ast.Node.Index,9715 node: Ast.Node.Index,
9716 type_inst: Zir.Inst.Ref,9716 type_inst: Zir.Inst.Ref,
9717 align_inst: Zir.Inst.Ref,9717 align_inst: Zir.Inst.Ref,
9718 is_const: bool,9718 is_const: bool,
...@@ -9763,7 +9763,7 @@ const GenZir = struct {...@@ -9763,7 +9763,7 @@ const GenZir = struct {
9763 gz: *GenZir,9763 gz: *GenZir,
9764 args: struct {9764 args: struct {
9765 /// Absolute node index. This function does the conversion to offset from Decl.9765 /// Absolute node index. This function does the conversion to offset from Decl.
9766 node: ast.Node.Index,9766 node: Ast.Node.Index,
9767 asm_source: u32,9767 asm_source: u32,
9768 output_type_bits: u32,9768 output_type_bits: u32,
9769 is_volatile: bool,9769 is_volatile: bool,
...@@ -9820,7 +9820,7 @@ const GenZir = struct {...@@ -9820,7 +9820,7 @@ const GenZir = struct {
9820 /// Note that this returns a `Zir.Inst.Index` not a ref.9820 /// Note that this returns a `Zir.Inst.Index` not a ref.
9821 /// Does *not* append the block instruction to the scope.9821 /// Does *not* append the block instruction to the scope.
9822 /// Leaves the `payload_index` field undefined.9822 /// 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 {
9824 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);9824 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
9825 const gpa = gz.astgen.gpa;9825 const gpa = gz.astgen.gpa;
9826 try gz.astgen.instructions.append(gpa, .{9826 try gz.astgen.instructions.append(gpa, .{
...@@ -9835,7 +9835,7 @@ const GenZir = struct {...@@ -9835,7 +9835,7 @@ const GenZir = struct {
98359835
9836 /// Note that this returns a `Zir.Inst.Index` not a ref.9836 /// Note that this returns a `Zir.Inst.Index` not a ref.
9837 /// Leaves the `payload_index` field undefined.9837 /// 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 {
9839 const gpa = gz.astgen.gpa;9839 const gpa = gz.astgen.gpa;
9840 try gz.instructions.ensureUnusedCapacity(gpa, 1);9840 try gz.instructions.ensureUnusedCapacity(gpa, 1);
9841 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);9841 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
...@@ -9851,7 +9851,7 @@ const GenZir = struct {...@@ -9851,7 +9851,7 @@ const GenZir = struct {
9851 }9851 }
98529852
9853 fn setStruct(gz: *GenZir, inst: Zir.Inst.Index, args: struct {9853 fn setStruct(gz: *GenZir, inst: Zir.Inst.Index, args: struct {
9854 src_node: ast.Node.Index,9854 src_node: Ast.Node.Index,
9855 body_len: u32,9855 body_len: u32,
9856 fields_len: u32,9856 fields_len: u32,
9857 decls_len: u32,9857 decls_len: u32,
...@@ -9896,7 +9896,7 @@ const GenZir = struct {...@@ -9896,7 +9896,7 @@ const GenZir = struct {
9896 }9896 }
98979897
9898 fn setUnion(gz: *GenZir, inst: Zir.Inst.Index, args: struct {9898 fn setUnion(gz: *GenZir, inst: Zir.Inst.Index, args: struct {
9899 src_node: ast.Node.Index,9899 src_node: Ast.Node.Index,
9900 tag_type: Zir.Inst.Ref,9900 tag_type: Zir.Inst.Ref,
9901 body_len: u32,9901 body_len: u32,
9902 fields_len: u32,9902 fields_len: u32,
...@@ -9946,7 +9946,7 @@ const GenZir = struct {...@@ -9946,7 +9946,7 @@ const GenZir = struct {
9946 }9946 }
99479947
9948 fn setEnum(gz: *GenZir, inst: Zir.Inst.Index, args: struct {9948 fn setEnum(gz: *GenZir, inst: Zir.Inst.Index, args: struct {
9949 src_node: ast.Node.Index,9949 src_node: Ast.Node.Index,
9950 tag_type: Zir.Inst.Ref,9950 tag_type: Zir.Inst.Ref,
9951 body_len: u32,9951 body_len: u32,
9952 fields_len: u32,9952 fields_len: u32,
...@@ -10019,7 +10019,7 @@ const GenZir = struct {...@@ -10019,7 +10019,7 @@ const GenZir = struct {
10019 return new_index;10019 return new_index;
10020 }10020 }
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 {
10023 switch (rl) {10023 switch (rl) {
10024 .ptr => |ret_ptr| _ = try gz.addUnNode(.ret_load, ret_ptr, node),10024 .ptr => |ret_ptr| _ = try gz.addUnNode(.ret_load, ret_ptr, node),
10025 .ty => _ = try gz.addUnNode(.ret_node, operand, node),10025 .ty => _ = try gz.addUnNode(.ret_node, operand, node),
...@@ -10052,7 +10052,7 @@ fn detectLocalShadowing(...@@ -10052,7 +10052,7 @@ fn detectLocalShadowing(
10052 astgen: *AstGen,10052 astgen: *AstGen,
10053 scope: *Scope,10053 scope: *Scope,
10054 ident_name: u32,10054 ident_name: u32,
10055 name_token: ast.TokenIndex,10055 name_token: Ast.TokenIndex,
10056 token_bytes: []const u8,10056 token_bytes: []const u8,
10057) !void {10057) !void {
10058 const gpa = astgen.gpa;10058 const gpa = astgen.gpa;
...@@ -10157,7 +10157,7 @@ fn refToIndex(inst: Zir.Inst.Ref) ?Zir.Inst.Index {...@@ -10157,7 +10157,7 @@ fn refToIndex(inst: Zir.Inst.Ref) ?Zir.Inst.Index {
10157 }10157 }
10158}10158}
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 {
10161 const gpa = astgen.gpa;10161 const gpa = astgen.gpa;
10162 const tree = astgen.tree;10162 const tree = astgen.tree;
10163 const node_tags = tree.nodes.items(.tag);10163 const node_tags = tree.nodes.items(.tag);
src/Compilation.zig+1-1
...@@ -2408,7 +2408,7 @@ const AstGenSrc = union(enum) {...@@ -2408,7 +2408,7 @@ const AstGenSrc = union(enum) {
2408 root,2408 root,
2409 import: struct {2409 import: struct {
2410 importing_file: *Module.Scope.File,2410 importing_file: *Module.Scope.File,
2411 import_tok: std.zig.ast.TokenIndex,2411 import_tok: std.zig.Ast.TokenIndex,
2412 },2412 },
2413};2413};
24142414
src/Module.zig+24-24
...@@ -11,7 +11,7 @@ const log = std.log.scoped(.module);...@@ -11,7 +11,7 @@ const log = std.log.scoped(.module);
11const BigIntConst = std.math.big.int.Const;11const BigIntConst = std.math.big.int.Const;
12const BigIntMutable = std.math.big.int.Mutable;12const BigIntMutable = std.math.big.int.Mutable;
13const Target = std.Target;13const Target = std.Target;
14const ast = std.zig.ast;14const Ast = std.zig.Ast;
1515
16const Module = @This();16const Module = @This();
17const Compilation = @import("Compilation.zig");17const Compilation = @import("Compilation.zig");
...@@ -291,7 +291,7 @@ pub const Decl = struct {...@@ -291,7 +291,7 @@ pub const Decl = struct {
291 generation: u32,291 generation: u32,
292 /// The AST node index of this declaration.292 /// The AST node index of this declaration.
293 /// Must be recomputed when the corresponding source file is modified.293 /// Must be recomputed when the corresponding source file is modified.
294 src_node: ast.Node.Index,294 src_node: Ast.Node.Index,
295 /// Line number corresponding to `src_node`. Stored separately so that source files295 /// Line number corresponding to `src_node`. Stored separately so that source files
296 /// do not need to be loaded into memory in order to compute debug line numbers.296 /// do not need to be loaded into memory in order to compute debug line numbers.
297 src_line: u32,297 src_line: u32,
...@@ -499,19 +499,19 @@ pub const Decl = struct {...@@ -499,19 +499,19 @@ pub const Decl = struct {
499 return decl.src_line + offset;499 return decl.src_line + offset;
500 }500 }
501501
502 pub fn relativeToNodeIndex(decl: Decl, offset: i32) ast.Node.Index {502 pub fn relativeToNodeIndex(decl: Decl, offset: i32) Ast.Node.Index {
503 return @bitCast(ast.Node.Index, offset + @bitCast(i32, decl.src_node));503 return @bitCast(Ast.Node.Index, offset + @bitCast(i32, decl.src_node));
504 }504 }
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 {
507 return @bitCast(i32, node_index) - @bitCast(i32, decl.src_node);507 return @bitCast(i32, node_index) - @bitCast(i32, decl.src_node);
508 }508 }
509509
510 pub fn tokSrcLoc(decl: Decl, token_index: ast.TokenIndex) LazySrcLoc {510 pub fn tokSrcLoc(decl: Decl, token_index: Ast.TokenIndex) LazySrcLoc {
511 return .{ .token_offset = token_index - decl.srcToken() };511 return .{ .token_offset = token_index - decl.srcToken() };
512 }512 }
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 {
515 return .{ .node_offset = decl.nodeIndexToRelative(node_index) };515 return .{ .node_offset = decl.nodeIndexToRelative(node_index) };
516 }516 }
517517
...@@ -527,7 +527,7 @@ pub const Decl = struct {...@@ -527,7 +527,7 @@ pub const Decl = struct {
527 };527 };
528 }528 }
529529
530 pub fn srcToken(decl: Decl) ast.TokenIndex {530 pub fn srcToken(decl: Decl) Ast.TokenIndex {
531 const tree = &decl.namespace.file_scope.tree;531 const tree = &decl.namespace.file_scope.tree;
532 return tree.firstToken(decl.src_node);532 return tree.firstToken(decl.src_node);
533 }533 }
...@@ -1121,7 +1121,7 @@ pub const Scope = struct {...@@ -1121,7 +1121,7 @@ pub const Scope = struct {
1121 /// Whether this is populated depends on `status`.1121 /// Whether this is populated depends on `status`.
1122 stat_mtime: i128,1122 stat_mtime: i128,
1123 /// Whether this is populated or not depends on `tree_loaded`.1123 /// Whether this is populated or not depends on `tree_loaded`.
1124 tree: ast.Tree,1124 tree: Ast,
1125 /// Whether this is populated or not depends on `zir_loaded`.1125 /// Whether this is populated or not depends on `zir_loaded`.
1126 zir: Zir,1126 zir: Zir,
1127 /// Package that this file is a part of, managed externally.1127 /// Package that this file is a part of, managed externally.
...@@ -1220,7 +1220,7 @@ pub const Scope = struct {...@@ -1220,7 +1220,7 @@ pub const Scope = struct {
1220 return source;1220 return source;
1221 }1221 }
12221222
1223 pub fn getTree(file: *File, gpa: *Allocator) !*const ast.Tree {1223 pub fn getTree(file: *File, gpa: *Allocator) !*const Ast {
1224 if (file.tree_loaded) return &file.tree;1224 if (file.tree_loaded) return &file.tree;
12251225
1226 const source = try file.getSource(gpa);1226 const source = try file.getSource(gpa);
...@@ -1565,17 +1565,17 @@ pub const ErrorMsg = struct {...@@ -1565,17 +1565,17 @@ pub const ErrorMsg = struct {
1565pub const SrcLoc = struct {1565pub const SrcLoc = struct {
1566 file_scope: *Scope.File,1566 file_scope: *Scope.File,
1567 /// Might be 0 depending on tag of `lazy`.1567 /// Might be 0 depending on tag of `lazy`.
1568 parent_decl_node: ast.Node.Index,1568 parent_decl_node: Ast.Node.Index,
1569 /// Relative to `parent_decl_node`.1569 /// Relative to `parent_decl_node`.
1570 lazy: LazySrcLoc,1570 lazy: LazySrcLoc,
15711571
1572 pub fn declSrcToken(src_loc: SrcLoc) ast.TokenIndex {1572 pub fn declSrcToken(src_loc: SrcLoc) Ast.TokenIndex {
1573 const tree = src_loc.file_scope.tree;1573 const tree = src_loc.file_scope.tree;
1574 return tree.firstToken(src_loc.parent_decl_node);1574 return tree.firstToken(src_loc.parent_decl_node);
1575 }1575 }
15761576
1577 pub fn declRelativeToNodeIndex(src_loc: SrcLoc, offset: i32) ast.TokenIndex {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));1578 return @bitCast(Ast.Node.Index, offset + @bitCast(i32, src_loc.parent_decl_node));
1579 }1579 }
15801580
1581 pub fn byteOffset(src_loc: SrcLoc, gpa: *Allocator) !u32 {1581 pub fn byteOffset(src_loc: SrcLoc, gpa: *Allocator) !u32 {
...@@ -1701,7 +1701,7 @@ pub const SrcLoc = struct {...@@ -1701,7 +1701,7 @@ pub const SrcLoc = struct {
1701 const tree = try src_loc.file_scope.getTree(gpa);1701 const tree = try src_loc.file_scope.getTree(gpa);
1702 const node_tags = tree.nodes.items(.tag);1702 const node_tags = tree.nodes.items(.tag);
1703 const node = src_loc.declRelativeToNodeIndex(node_off);1703 const node = src_loc.declRelativeToNodeIndex(node_off);
1704 var params: [1]ast.Node.Index = undefined;1704 var params: [1]Ast.Node.Index = undefined;
1705 const full = switch (node_tags[node]) {1705 const full = switch (node_tags[node]) {
1706 .call_one,1706 .call_one,
1707 .call_one_comma,1707 .call_one_comma,
...@@ -1831,7 +1831,7 @@ pub const SrcLoc = struct {...@@ -1831,7 +1831,7 @@ pub const SrcLoc = struct {
1831 const node_datas = tree.nodes.items(.data);1831 const node_datas = tree.nodes.items(.data);
1832 const node_tags = tree.nodes.items(.tag);1832 const node_tags = tree.nodes.items(.tag);
1833 const main_tokens = tree.nodes.items(.main_token);1833 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);
1835 const case_nodes = tree.extra_data[extra.start..extra.end];1835 const case_nodes = tree.extra_data[extra.start..extra.end];
1836 for (case_nodes) |case_node| {1836 for (case_nodes) |case_node| {
1837 const case = switch (node_tags[case_node]) {1837 const case = switch (node_tags[case_node]) {
...@@ -1857,7 +1857,7 @@ pub const SrcLoc = struct {...@@ -1857,7 +1857,7 @@ pub const SrcLoc = struct {
1857 const node_datas = tree.nodes.items(.data);1857 const node_datas = tree.nodes.items(.data);
1858 const node_tags = tree.nodes.items(.tag);1858 const node_tags = tree.nodes.items(.tag);
1859 const main_tokens = tree.nodes.items(.main_token);1859 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);
1861 const case_nodes = tree.extra_data[extra.start..extra.end];1861 const case_nodes = tree.extra_data[extra.start..extra.end];
1862 for (case_nodes) |case_node| {1862 for (case_nodes) |case_node| {
1863 const case = switch (node_tags[case_node]) {1863 const case = switch (node_tags[case_node]) {
...@@ -1886,7 +1886,7 @@ pub const SrcLoc = struct {...@@ -1886,7 +1886,7 @@ pub const SrcLoc = struct {
1886 const node_datas = tree.nodes.items(.data);1886 const node_datas = tree.nodes.items(.data);
1887 const node_tags = tree.nodes.items(.tag);1887 const node_tags = tree.nodes.items(.tag);
1888 const node = src_loc.declRelativeToNodeIndex(node_off);1888 const node = src_loc.declRelativeToNodeIndex(node_off);
1889 var params: [1]ast.Node.Index = undefined;1889 var params: [1]Ast.Node.Index = undefined;
1890 const full = switch (node_tags[node]) {1890 const full = switch (node_tags[node]) {
1891 .fn_proto_simple => tree.fnProtoSimple(&params, node),1891 .fn_proto_simple => tree.fnProtoSimple(&params, node),
1892 .fn_proto_multi => tree.fnProtoMulti(node),1892 .fn_proto_multi => tree.fnProtoMulti(node),
...@@ -1911,7 +1911,7 @@ pub const SrcLoc = struct {...@@ -1911,7 +1911,7 @@ pub const SrcLoc = struct {
1911 const tree = try src_loc.file_scope.getTree(gpa);1911 const tree = try src_loc.file_scope.getTree(gpa);
1912 const node_tags = tree.nodes.items(.tag);1912 const node_tags = tree.nodes.items(.tag);
1913 const node = src_loc.declRelativeToNodeIndex(node_off);1913 const node = src_loc.declRelativeToNodeIndex(node_off);
1914 var params: [1]ast.Node.Index = undefined;1914 var params: [1]Ast.Node.Index = undefined;
1915 const full = switch (node_tags[node]) {1915 const full = switch (node_tags[node]) {
1916 .fn_proto_simple => tree.fnProtoSimple(&params, node),1916 .fn_proto_simple => tree.fnProtoSimple(&params, node),
1917 .fn_proto_multi => tree.fnProtoMulti(node),1917 .fn_proto_multi => tree.fnProtoMulti(node),
...@@ -1941,7 +1941,7 @@ pub const SrcLoc = struct {...@@ -1941,7 +1941,7 @@ pub const SrcLoc = struct {
1941 const node_datas = tree.nodes.items(.data);1941 const node_datas = tree.nodes.items(.data);
1942 const node_tags = tree.nodes.items(.tag);1942 const node_tags = tree.nodes.items(.tag);
1943 const parent_node = src_loc.declRelativeToNodeIndex(node_off);1943 const parent_node = src_loc.declRelativeToNodeIndex(node_off);
1944 var params: [1]ast.Node.Index = undefined;1944 var params: [1]Ast.Node.Index = undefined;
1945 const full = switch (node_tags[parent_node]) {1945 const full = switch (node_tags[parent_node]) {
1946 .fn_proto_simple => tree.fnProtoSimple(&params, parent_node),1946 .fn_proto_simple => tree.fnProtoSimple(&params, parent_node),
1947 .fn_proto_multi => tree.fnProtoMulti(parent_node),1947 .fn_proto_multi => tree.fnProtoMulti(parent_node),
...@@ -3967,7 +3967,7 @@ fn markOutdatedDecl(mod: *Module, decl: *Decl) !void {...@@ -3967,7 +3967,7 @@ fn markOutdatedDecl(mod: *Module, decl: *Decl) !void {
3967 decl.analysis = .outdated;3967 decl.analysis = .outdated;
3968}3968}
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 {
3971 // If we have emit-h then we must allocate a bigger structure to store the emit-h state.3971 // If we have emit-h then we must allocate a bigger structure to store the emit-h state.
3972 const new_decl: *Decl = if (mod.emit_h != null) blk: {3972 const new_decl: *Decl = if (mod.emit_h != null) blk: {
3973 const parent_struct = try mod.gpa.create(DeclPlusEmitH);3973 const parent_struct = try mod.gpa.create(DeclPlusEmitH);
...@@ -4237,7 +4237,7 @@ pub fn fail(...@@ -4237,7 +4237,7 @@ pub fn fail(
4237pub fn failTok(4237pub fn failTok(
4238 mod: *Module,4238 mod: *Module,
4239 scope: *Scope,4239 scope: *Scope,
4240 token_index: ast.TokenIndex,4240 token_index: Ast.TokenIndex,
4241 comptime format: []const u8,4241 comptime format: []const u8,
4242 args: anytype,4242 args: anytype,
4243) CompileError {4243) CompileError {
...@@ -4250,7 +4250,7 @@ pub fn failTok(...@@ -4250,7 +4250,7 @@ pub fn failTok(
4250pub fn failNode(4250pub fn failNode(
4251 mod: *Module,4251 mod: *Module,
4252 scope: *Scope,4252 scope: *Scope,
4253 node_index: ast.Node.Index,4253 node_index: Ast.Node.Index,
4254 comptime format: []const u8,4254 comptime format: []const u8,
4255 args: anytype,4255 args: anytype,
4256) CompileError {4256) CompileError {
...@@ -4455,7 +4455,7 @@ pub const SwitchProngSrc = union(enum) {...@@ -4455,7 +4455,7 @@ pub const SwitchProngSrc = union(enum) {
4455 const main_tokens = tree.nodes.items(.main_token);4455 const main_tokens = tree.nodes.items(.main_token);
4456 const node_datas = tree.nodes.items(.data);4456 const node_datas = tree.nodes.items(.data);
4457 const node_tags = tree.nodes.items(.tag);4457 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);
4459 const case_nodes = tree.extra_data[extra.start..extra.end];4459 const case_nodes = tree.extra_data[extra.start..extra.end];
44604460
4461 var multi_i: u32 = 0;4461 var multi_i: u32 = 0;
src/Sema.zig+3-3
...@@ -10177,7 +10177,7 @@ fn typeHasOnePossibleValue(...@@ -10177,7 +10177,7 @@ fn typeHasOnePossibleValue(
10177 };10177 };
10178}10178}
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 {
10181 return block.src_decl.namespace.file_scope.getTree(sema.gpa) catch |err| {10181 return block.src_decl.namespace.file_scope.getTree(sema.gpa) catch |err| {
10182 log.err("unable to load AST to report compile error: {s}", .{@errorName(err)});10182 log.err("unable to load AST to report compile error: {s}", .{@errorName(err)});
10183 return error.AnalysisFail;10183 return error.AnalysisFail;
...@@ -10186,14 +10186,14 @@ fn getAstTree(sema: *Sema, block: *Scope.Block) CompileError!*const std.zig.ast....@@ -10186,14 +10186,14 @@ fn getAstTree(sema: *Sema, block: *Scope.Block) CompileError!*const std.zig.ast.
1018610186
10187fn enumFieldSrcLoc(10187fn enumFieldSrcLoc(
10188 decl: *Decl,10188 decl: *Decl,
10189 tree: std.zig.ast.Tree,10189 tree: std.zig.Ast,
10190 node_offset: i32,10190 node_offset: i32,
10191 field_index: usize,10191 field_index: usize,
10192) LazySrcLoc {10192) LazySrcLoc {
10193 @setCold(true);10193 @setCold(true);
10194 const enum_node = decl.relativeToNodeIndex(node_offset);10194 const enum_node = decl.relativeToNodeIndex(node_offset);
10195 const node_tags = tree.nodes.items(.tag);10195 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;
10197 const container_decl = switch (node_tags[enum_node]) {10197 const container_decl = switch (node_tags[enum_node]) {
10198 .container_decl,10198 .container_decl,
10199 .container_decl_trailing,10199 .container_decl_trailing,
src/Zir.zig+9-9
...@@ -16,7 +16,7 @@ const Allocator = std.mem.Allocator;...@@ -16,7 +16,7 @@ const Allocator = std.mem.Allocator;
16const assert = std.debug.assert;16const assert = std.debug.assert;
17const BigIntConst = std.math.big.int.Const;17const BigIntConst = std.math.big.int.Const;
18const BigIntMutable = std.math.big.int.Mutable;18const BigIntMutable = std.math.big.int.Mutable;
19const ast = std.zig.ast;19const Ast = std.zig.Ast;
2020
21const Zir = @This();21const Zir = @This();
22const Type = @import("type.zig").Type;22const Type = @import("type.zig").Type;
...@@ -2092,7 +2092,7 @@ pub const Inst = struct {...@@ -2092,7 +2092,7 @@ pub const Inst = struct {
2092 /// Used for unary operators, with a token source location.2092 /// Used for unary operators, with a token source location.
2093 un_tok: struct {2093 un_tok: struct {
2094 /// Offset from Decl AST token index.2094 /// Offset from Decl AST token index.
2095 src_tok: ast.TokenIndex,2095 src_tok: Ast.TokenIndex,
2096 /// The meaning of this operand depends on the corresponding `Tag`.2096 /// The meaning of this operand depends on the corresponding `Tag`.
2097 operand: Ref,2097 operand: Ref,
20982098
...@@ -2114,7 +2114,7 @@ pub const Inst = struct {...@@ -2114,7 +2114,7 @@ pub const Inst = struct {
2114 },2114 },
2115 pl_tok: struct {2115 pl_tok: struct {
2116 /// Offset from Decl AST token index.2116 /// Offset from Decl AST token index.
2117 src_tok: ast.TokenIndex,2117 src_tok: Ast.TokenIndex,
2118 /// index into extra.2118 /// index into extra.
2119 /// `Tag` determines what lives there.2119 /// `Tag` determines what lives there.
2120 payload_index: u32,2120 payload_index: u32,
...@@ -2150,7 +2150,7 @@ pub const Inst = struct {...@@ -2150,7 +2150,7 @@ pub const Inst = struct {
2150 }2150 }
2151 },2151 },
2152 /// Offset from Decl AST token index.2152 /// Offset from Decl AST token index.
2153 tok: ast.TokenIndex,2153 tok: Ast.TokenIndex,
2154 /// Offset from Decl AST node index.2154 /// Offset from Decl AST node index.
2155 node: i32,2155 node: i32,
2156 int: u64,2156 int: u64,
...@@ -2878,9 +2878,9 @@ pub const Inst = struct {...@@ -2878,9 +2878,9 @@ pub const Inst = struct {
2878 pub const Item = struct {2878 pub const Item = struct {
2879 /// null terminated string index2879 /// null terminated string index
2880 msg: u32,2880 msg: u32,
2881 node: ast.Node.Index,2881 node: Ast.Node.Index,
2882 /// If node is 0 then this will be populated.2882 /// If node is 0 then this will be populated.
2883 token: ast.TokenIndex,2883 token: Ast.TokenIndex,
2884 /// Can be used in combination with `token`.2884 /// Can be used in combination with `token`.
2885 byte_offset: u32,2885 byte_offset: u32,
2886 /// 0 or a payload index of a `Block`, each is a payload2886 /// 0 or a payload index of a `Block`, each is a payload
...@@ -2897,7 +2897,7 @@ pub const Inst = struct {...@@ -2897,7 +2897,7 @@ pub const Inst = struct {
2897 /// null terminated string index2897 /// null terminated string index
2898 name: u32,2898 name: u32,
2899 /// points to the import name2899 /// points to the import name
2900 token: ast.TokenIndex,2900 token: Ast.TokenIndex,
2901 };2901 };
2902 };2902 };
2903};2903};
...@@ -2912,8 +2912,8 @@ const Writer = struct {...@@ -2912,8 +2912,8 @@ const Writer = struct {
2912 indent: u32,2912 indent: u32,
2913 parent_decl_node: u32,2913 parent_decl_node: u32,
29142914
2915 fn relativeToNodeIndex(self: *Writer, offset: i32) ast.Node.Index {2915 fn relativeToNodeIndex(self: *Writer, offset: i32) Ast.Node.Index {
2916 return @bitCast(ast.Node.Index, offset + @bitCast(i32, self.parent_decl_node));2916 return @bitCast(Ast.Node.Index, offset + @bitCast(i32, self.parent_decl_node));
2917 }2917 }
29182918
2919 fn writeInstToStream(2919 fn writeInstToStream(
src/main.zig+9-9
...@@ -6,7 +6,7 @@ const mem = std.mem;...@@ -6,7 +6,7 @@ const mem = std.mem;
6const process = std.process;6const process = std.process;
7const Allocator = mem.Allocator;7const Allocator = mem.Allocator;
8const ArrayList = std.ArrayList;8const ArrayList = std.ArrayList;
9const ast = std.zig.ast;9const Ast = std.zig.Ast;
10const warn = std.log.warn;10const warn = std.log.warn;
1111
12const Compilation = @import("Compilation.zig");12const Compilation = @import("Compilation.zig");
...@@ -3423,8 +3423,8 @@ fn fmtPathFile(...@@ -3423,8 +3423,8 @@ fn fmtPathFile(
3423fn printErrMsgToStdErr(3423fn printErrMsgToStdErr(
3424 gpa: *mem.Allocator,3424 gpa: *mem.Allocator,
3425 arena: *mem.Allocator,3425 arena: *mem.Allocator,
3426 parse_error: ast.Error,3426 parse_error: Ast.Error,
3427 tree: ast.Tree,3427 tree: Ast,
3428 path: []const u8,3428 path: []const u8,
3429 color: Color,3429 color: Color,
3430) !void {3430) !void {
...@@ -4029,12 +4029,12 @@ pub fn cmdAstCheck(...@@ -4029,12 +4029,12 @@ pub fn cmdAstCheck(
4029 }4029 }
40304030
4031 {4031 {
4032 const token_bytes = @sizeOf(std.zig.ast.TokenList) +4032 const token_bytes = @sizeOf(Ast.TokenList) +
4033 file.tree.tokens.len * (@sizeOf(std.zig.Token.Tag) + @sizeOf(std.zig.ast.ByteOffset));4033 file.tree.tokens.len * (@sizeOf(std.zig.Token.Tag) + @sizeOf(Ast.ByteOffset));
4034 const tree_bytes = @sizeOf(std.zig.ast.Tree) + file.tree.nodes.len *4034 const tree_bytes = @sizeOf(Ast) + file.tree.nodes.len *
4035 (@sizeOf(std.zig.ast.Node.Tag) +4035 (@sizeOf(Ast.Node.Tag) +
4036 @sizeOf(std.zig.ast.Node.Data) +4036 @sizeOf(Ast.Node.Data) +
4037 @sizeOf(std.zig.ast.TokenIndex));4037 @sizeOf(Ast.TokenIndex));
4038 const instruction_bytes = file.zir.instructions.len *4038 const instruction_bytes = file.zir.instructions.len *
4039 // Here we don't use @sizeOf(Zir.Inst.Data) because it would include4039 // Here we don't use @sizeOf(Zir.Inst.Data) because it would include
4040 // the debug safety tag but we want to measure release size.4040 // the debug safety tag but we want to measure release size.
src/translate_c.zig+2-2
...@@ -356,7 +356,7 @@ pub fn translate(...@@ -356,7 +356,7 @@ pub fn translate(
356 args_end: [*]?[*]const u8,356 args_end: [*]?[*]const u8,
357 errors: *[]ClangErrMsg,357 errors: *[]ClangErrMsg,
358 resources_path: [*:0]const u8,358 resources_path: [*:0]const u8,
359) !std.zig.ast.Tree {359) !std.zig.Ast {
360 const ast_unit = clang.LoadFromCommandLine(360 const ast_unit = clang.LoadFromCommandLine(
361 args_begin,361 args_begin,
362 args_end,362 args_end,
...@@ -369,7 +369,7 @@ pub fn translate(...@@ -369,7 +369,7 @@ pub fn translate(
369 };369 };
370 defer ast_unit.delete();370 defer ast_unit.delete();
371371
372 // For memory that has the same lifetime as the Tree that we return372 // For memory that has the same lifetime as the Ast that we return
373 // from this function.373 // from this function.
374 var arena = std.heap.ArenaAllocator.init(gpa);374 var arena = std.heap.ArenaAllocator.init(gpa);
375 errdefer arena.deinit();375 errdefer arena.deinit();
src/translate_c/ast.zig+22-22
...@@ -714,9 +714,9 @@ pub const Payload = struct {...@@ -714,9 +714,9 @@ pub const Payload = struct {
714 };714 };
715};715};
716716
717/// Converts the nodes into a Zig ast.717/// Converts the nodes into a Zig Ast.
718/// Caller must free the source slice.718/// 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 {
720 var ctx = Context{720 var ctx = Context{
721 .gpa = gpa,721 .gpa = gpa,
722 .buf = std.ArrayList(u8).init(gpa),722 .buf = std.ArrayList(u8).init(gpa),
...@@ -767,7 +767,7 @@ pub fn render(gpa: *Allocator, nodes: []const Node) !std.zig.ast.Tree {...@@ -767,7 +767,7 @@ pub fn render(gpa: *Allocator, nodes: []const Node) !std.zig.ast.Tree {
767 .start = @intCast(u32, ctx.buf.items.len),767 .start = @intCast(u32, ctx.buf.items.len),
768 });768 });
769769
770 return std.zig.ast.Tree{770 return std.zig.Ast{
771 .source = try ctx.buf.toOwnedSliceSentinel(0),771 .source = try ctx.buf.toOwnedSliceSentinel(0),
772 .tokens = ctx.tokens.toOwnedSlice(),772 .tokens = ctx.tokens.toOwnedSlice(),
773 .nodes = ctx.nodes.toOwnedSlice(),773 .nodes = ctx.nodes.toOwnedSlice(),
...@@ -776,17 +776,17 @@ pub fn render(gpa: *Allocator, nodes: []const Node) !std.zig.ast.Tree {...@@ -776,17 +776,17 @@ pub fn render(gpa: *Allocator, nodes: []const Node) !std.zig.ast.Tree {
776 };776 };
777}777}
778778
779const NodeIndex = std.zig.ast.Node.Index;779const NodeIndex = std.zig.Ast.Node.Index;
780const NodeSubRange = std.zig.ast.Node.SubRange;780const NodeSubRange = std.zig.Ast.Node.SubRange;
781const TokenIndex = std.zig.ast.TokenIndex;781const TokenIndex = std.zig.Ast.TokenIndex;
782const TokenTag = std.zig.Token.Tag;782const TokenTag = std.zig.Token.Tag;
783783
784const Context = struct {784const Context = struct {
785 gpa: *Allocator,785 gpa: *Allocator,
786 buf: std.ArrayList(u8) = .{},786 buf: std.ArrayList(u8) = .{},
787 nodes: std.zig.ast.NodeList = .{},787 nodes: std.zig.Ast.NodeList = .{},
788 extra_data: std.ArrayListUnmanaged(std.zig.ast.Node.Index) = .{},788 extra_data: std.ArrayListUnmanaged(std.zig.Ast.Node.Index) = .{},
789 tokens: std.zig.ast.TokenList = .{},789 tokens: std.zig.Ast.TokenList = .{},
790790
791 fn addTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex {791 fn addTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex {
792 const start_index = c.buf.items.len;792 const start_index = c.buf.items.len;
...@@ -831,7 +831,7 @@ const Context = struct {...@@ -831,7 +831,7 @@ const Context = struct {
831 };831 };
832 }832 }
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 {
835 const result = @intCast(NodeIndex, c.nodes.len);835 const result = @intCast(NodeIndex, c.nodes.len);
836 try c.nodes.append(c.gpa, elem);836 try c.nodes.append(c.gpa, elem);
837 return result;837 return result;
...@@ -1166,7 +1166,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1166,7 +1166,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1166 .main_token = l_bracket,1166 .main_token = l_bracket,
1167 .data = .{1167 .data = .{
1168 .lhs = string,1168 .lhs = string,
1169 .rhs = try c.addExtra(std.zig.ast.Node.Slice{1169 .rhs = try c.addExtra(std.zig.Ast.Node.Slice{
1170 .start = start,1170 .start = start,
1171 .end = end,1171 .end = end,
1172 }),1172 }),
...@@ -1601,7 +1601,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1601,7 +1601,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1601 .main_token = while_tok,1601 .main_token = while_tok,
1602 .data = .{1602 .data = .{
1603 .lhs = cond,1603 .lhs = cond,
1604 .rhs = try c.addExtra(std.zig.ast.Node.WhileCont{1604 .rhs = try c.addExtra(std.zig.Ast.Node.WhileCont{
1605 .cont_expr = cont_expr,1605 .cont_expr = cont_expr,
1606 .then_expr = body,1606 .then_expr = body,
1607 }),1607 }),
...@@ -1654,7 +1654,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1654,7 +1654,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1654 .main_token = if_tok,1654 .main_token = if_tok,
1655 .data = .{1655 .data = .{
1656 .lhs = cond,1656 .lhs = cond,
1657 .rhs = try c.addExtra(std.zig.ast.Node.If{1657 .rhs = try c.addExtra(std.zig.Ast.Node.If{
1658 .then_expr = then_expr,1658 .then_expr = then_expr,
1659 .else_expr = else_expr,1659 .else_expr = else_expr,
1660 }),1660 }),
...@@ -2175,7 +2175,7 @@ fn renderNullSentinelArrayType(c: *Context, len: usize, elem_type: Node) !NodeIn...@@ -2175,7 +2175,7 @@ fn renderNullSentinelArrayType(c: *Context, len: usize, elem_type: Node) !NodeIn
2175 .main_token = l_bracket,2175 .main_token = l_bracket,
2176 .data = .{2176 .data = .{
2177 .lhs = len_expr,2177 .lhs = len_expr,
2178 .rhs = try c.addExtra(std.zig.ast.Node.ArrayTypeSentinel{2178 .rhs = try c.addExtra(std.zig.Ast.Node.ArrayTypeSentinel{
2179 .sentinel = sentinel_expr,2179 .sentinel = sentinel_expr,
2180 .elem_type = elem_type_expr,2180 .elem_type = elem_type_expr,
2181 }),2181 }),
...@@ -2378,7 +2378,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {...@@ -2378,7 +2378,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
2378 }2378 }
2379}2379}
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 {
2382 const payload = @fieldParentPtr(Payload.UnOp, "base", node.ptr_otherwise).data;2382 const payload = @fieldParentPtr(Payload.UnOp, "base", node.ptr_otherwise).data;
2383 return c.addNode(.{2383 return c.addNode(.{
2384 .tag = tag,2384 .tag = tag,
...@@ -2390,7 +2390,7 @@ fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: T...@@ -2390,7 +2390,7 @@ fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: T
2390 });2390 });
2391}2391}
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 {
2394 const payload = @fieldParentPtr(Payload.BinOp, "base", node.ptr_otherwise).data;2394 const payload = @fieldParentPtr(Payload.BinOp, "base", node.ptr_otherwise).data;
2395 const lhs = try renderNodeGrouped(c, payload.lhs);2395 const lhs = try renderNodeGrouped(c, payload.lhs);
2396 return c.addNode(.{2396 return c.addNode(.{
...@@ -2403,7 +2403,7 @@ fn renderBinOpGrouped(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_ta...@@ -2403,7 +2403,7 @@ fn renderBinOpGrouped(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_ta
2403 });2403 });
2404}2404}
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 {
2407 const payload = @fieldParentPtr(Payload.BinOp, "base", node.ptr_otherwise).data;2407 const payload = @fieldParentPtr(Payload.BinOp, "base", node.ptr_otherwise).data;
2408 const lhs = try renderNode(c, payload.lhs);2408 const lhs = try renderNode(c, payload.lhs);
2409 return c.addNode(.{2409 return c.addNode(.{
...@@ -2604,7 +2604,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex {...@@ -2604,7 +2604,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex {
2604 .tag = .local_var_decl,2604 .tag = .local_var_decl,
2605 .main_token = mut_tok,2605 .main_token = mut_tok,
2606 .data = .{2606 .data = .{
2607 .lhs = try c.addExtra(std.zig.ast.Node.LocalVarDecl{2607 .lhs = try c.addExtra(std.zig.Ast.Node.LocalVarDecl{
2608 .type_node = type_node,2608 .type_node = type_node,
2609 .align_node = align_node,2609 .align_node = align_node,
2610 }),2610 }),
...@@ -2617,7 +2617,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex {...@@ -2617,7 +2617,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex {
2617 .tag = .global_var_decl,2617 .tag = .global_var_decl,
2618 .main_token = mut_tok,2618 .main_token = mut_tok,
2619 .data = .{2619 .data = .{
2620 .lhs = try c.addExtra(std.zig.ast.Node.GlobalVarDecl{2620 .lhs = try c.addExtra(std.zig.Ast.Node.GlobalVarDecl{
2621 .type_node = type_node,2621 .type_node = type_node,
2622 .align_node = align_node,2622 .align_node = align_node,
2623 .section_node = section_node,2623 .section_node = section_node,
...@@ -2709,7 +2709,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {...@@ -2709,7 +2709,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
2709 .tag = .fn_proto_one,2709 .tag = .fn_proto_one,
2710 .main_token = fn_token,2710 .main_token = fn_token,
2711 .data = .{2711 .data = .{
2712 .lhs = try c.addExtra(std.zig.ast.Node.FnProtoOne{2712 .lhs = try c.addExtra(std.zig.Ast.Node.FnProtoOne{
2713 .param = params.items[0],2713 .param = params.items[0],
2714 .align_expr = align_expr,2714 .align_expr = align_expr,
2715 .section_expr = section_expr,2715 .section_expr = section_expr,
...@@ -2723,7 +2723,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {...@@ -2723,7 +2723,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
2723 .tag = .fn_proto,2723 .tag = .fn_proto,
2724 .main_token = fn_token,2724 .main_token = fn_token,
2725 .data = .{2725 .data = .{
2726 .lhs = try c.addExtra(std.zig.ast.Node.FnProto{2726 .lhs = try c.addExtra(std.zig.Ast.Node.FnProto{
2727 .params_start = span.start,2727 .params_start = span.start,
2728 .params_end = span.end,2728 .params_end = span.end,
2729 .align_expr = align_expr,2729 .align_expr = align_expr,
...@@ -2781,7 +2781,7 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {...@@ -2781,7 +2781,7 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {
2781 .tag = .fn_proto_multi,2781 .tag = .fn_proto_multi,
2782 .main_token = fn_token,2782 .main_token = fn_token,
2783 .data = .{2783 .data = .{
2784 .lhs = try c.addExtra(std.zig.ast.Node.SubRange{2784 .lhs = try c.addExtra(std.zig.Ast.Node.SubRange{
2785 .start = span.start,2785 .start = span.start,
2786 .end = span.end,2786 .end = span.end,
2787 }),2787 }),