authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-13 21:40:12-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-13 21:40:12-07:00
logc2b4d51749c365b1f007df782e06a85c69456937
tree4870815c8ff341fd7307be697fd3975953d30398
parent24798b84ad818a4c6d6a6ee3e215ccbc49293b81

astgen: update a handful of expression types to new mem layout

break, continue, blocks, bit_not, negation, identifiers, string literals, integer literals, inline assembly also gave multiline string literals a different node tag from regular string literals, for code clarity and to avoid an unnecessary load from token_tags array.

4 files changed, 275 insertions(+), 191 deletions(-)

lib/std/zig/ast.zig+7-2
......@@ -283,6 +283,7 @@ pub const Tree = struct {
283283 .undefined_literal,
284284 .unreachable_literal,
285285 .string_literal,
286 .multiline_string_literal,
286287 .grouped_expression,
287288 .builtin_call_two,
288289 .builtin_call_two_comma,
......@@ -593,7 +594,7 @@ pub const Tree = struct {
593594 .field_access,
594595 .unwrap_optional,
595596 .grouped_expression,
596 .string_literal,
597 .multiline_string_literal,
597598 .error_set_decl,
598599 .asm_simple,
599600 .asm_output,
......@@ -614,6 +615,7 @@ pub const Tree = struct {
614615 .identifier,
615616 .deref,
616617 .enum_literal,
618 .string_literal,
617619 => return main_tokens[n] + end_offset,
618620
619621 .@"return" => if (datas[n].lhs != 0) {
......@@ -2826,11 +2828,14 @@ pub const Node = struct {
28262828 identifier,
28272829 /// lhs is the dot token index, rhs unused, main_token is the identifier.
28282830 enum_literal,
2831 /// main_token is the string literal token
2832 /// Both lhs and rhs unused.
2833 string_literal,
28292834 /// main_token is the first token index (redundant with lhs)
28302835 /// lhs is the first token index; rhs is the last token index.
28312836 /// Could be a series of multiline_string_literal_line tokens, or a single
28322837 /// string_literal token.
2833 string_literal,
2838 multiline_string_literal,
28342839 /// `(lhs)`. main_token is the `(`; rhs is the token index of the `)`.
28352840 grouped_expression,
28362841 /// `@a(lhs, rhs)`. lhs and rhs may be omitted.
lib/std/zig/parse.zig+6-6
......@@ -2595,8 +2595,8 @@ const Parser = struct {
25952595 .tag = .string_literal,
25962596 .main_token = main_token,
25972597 .data = .{
2598 .lhs = main_token,
2599 .rhs = main_token,
2598 .lhs = undefined,
2599 .rhs = undefined,
26002600 },
26012601 });
26022602 },
......@@ -2633,7 +2633,7 @@ const Parser = struct {
26332633 p.tok_i += 1;
26342634 }
26352635 return p.addNode(.{
2636 .tag = .string_literal,
2636 .tag = .multiline_string_literal,
26372637 .main_token = first_line,
26382638 .data = .{
26392639 .lhs = first_line,
......@@ -3996,8 +3996,8 @@ const Parser = struct {
39963996 .tag = .string_literal,
39973997 .main_token = main_token,
39983998 .data = .{
3999 .lhs = main_token,
4000 .rhs = main_token,
3999 .lhs = undefined,
4000 .rhs = undefined,
40014001 },
40024002 });
40034003 },
......@@ -4007,7 +4007,7 @@ const Parser = struct {
40074007 p.tok_i += 1;
40084008 }
40094009 return p.addNode(.{
4010 .tag = .string_literal,
4010 .tag = .multiline_string_literal,
40114011 .main_token = first_line,
40124012 .data = .{
40134013 .lhs = first_line,
lib/std/zig/render.zig+15-20
......@@ -153,29 +153,25 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
153153 .unreachable_literal,
154154 .undefined_literal,
155155 .anyframe_literal,
156 .string_literal,
156157 => return renderToken(ais, tree, main_tokens[node], space),
157158
158 .string_literal => switch (token_tags[main_tokens[node]]) {
159 .string_literal => try renderToken(ais, tree, main_tokens[node], space),
159 .multiline_string_literal => {
160 var locked_indents = ais.lockOneShotIndent();
161 try ais.maybeInsertNewline();
160162
161 .multiline_string_literal_line => {
162 var locked_indents = ais.lockOneShotIndent();
163 try ais.maybeInsertNewline();
163 var i = datas[node].lhs;
164 while (i <= datas[node].rhs) : (i += 1) try renderToken(ais, tree, i, .newline);
164165
165 var i = datas[node].lhs;
166 while (i <= datas[node].rhs) : (i += 1) try renderToken(ais, tree, i, .newline);
166 while (locked_indents > 0) : (locked_indents -= 1) ais.popIndent();
167167
168 while (locked_indents > 0) : (locked_indents -= 1) ais.popIndent();
169
170 switch (space) {
171 .none => {},
172 .semicolon => if (token_tags[i] == .semicolon) try renderToken(ais, tree, i, .newline),
173 .comma => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .newline),
174 .comma_space => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .space),
175 else => unreachable,
176 }
177 },
178 else => unreachable,
168 switch (space) {
169 .none => {},
170 .semicolon => if (token_tags[i] == .semicolon) try renderToken(ais, tree, i, .newline),
171 .comma => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .newline),
172 .comma_space => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .space),
173 else => unreachable,
174 }
179175 },
180176
181177 .error_value => {
......@@ -1850,8 +1846,7 @@ fn renderCall(
18501846 try renderExpression(ais, tree, param_node, Space.none);
18511847
18521848 // Unindent the comma for multiline string literals
1853 const is_multiline_string = node_tags[param_node] == .string_literal and
1854 token_tags[main_tokens[param_node]] == .multiline_string_literal_line;
1849 const is_multiline_string = node_tags[param_node] == .multiline_string_literal;
18551850 if (is_multiline_string) ais.popIndent();
18561851
18571852 const comma = tree.lastToken(param_node) + 1;
src/astgen.zig+247-163
......@@ -56,7 +56,8 @@ pub const ResultLoc = union(enum) {
5656};
5757
5858pub fn typeExpr(mod: *Module, scope: *Scope, type_node: ast.Node.Index) InnerError!*zir.Inst {
59 const type_src = scope.tree().token_locs[type_node.firstToken()].start;
59 const tree = scope.tree();
60 const type_src = token_starts[tree.firstToken(type_node)];
6061 const type_type = try addZIRInstConst(mod, scope, type_src, .{
6162 .ty = Type.initTag(.type),
6263 .val = Value.initTag(.type_type),
......@@ -258,18 +259,23 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
258259 .array_cat => return simpleBinOp(mod, scope, rl, node, .array_cat),
259260 .array_mult => return simpleBinOp(mod, scope, rl, node, .array_mul),
260261
261 .bool_and => return boolBinOp(mod, scope, rl, node),
262 .bool_or => return boolBinOp(mod, scope, rl, node),
262 .bool_and => return boolBinOp(mod, scope, rl, node, true),
263 .bool_or => return boolBinOp(mod, scope, rl, node, false),
263264
264265 .bool_not => return rvalue(mod, scope, rl, try boolNot(mod, scope, node)),
265266 .bit_not => return rvalue(mod, scope, rl, try bitNot(mod, scope, node)),
266267 .negation => return rvalue(mod, scope, rl, try negation(mod, scope, node, .sub)),
267268 .negation_wrap => return rvalue(mod, scope, rl, try negation(mod, scope, node, .subwrap)),
268269
269 .identifier => return try identifier(mod, scope, rl, node),
270 .@"asm" => return rvalue(mod, scope, rl, try assembly(mod, scope, node)),
271 .string_literal => return rvalue(mod, scope, rl, try stringLiteral(mod, scope, node)),
272 .integer_literal => return rvalue(mod, scope, rl, try integerLiteral(mod, scope, node)),
270 .identifier => return identifier(mod, scope, rl, node),
271
272 .asm_simple => return assembly(mod, scope, rl, tree.asmSimple(node)),
273 .@"asm" => return assembly(mod, scope, rl, tree.asmFull(node)),
274
275 .string_literal => return stringLiteral(mod, scope, rl, node),
276 .multiline_string_literal => return multilineStringLiteral(mod, scope, rl, node),
277
278 .integer_literal => return integerLiteral(mod, scope, rl, node),
273279 .builtin_call => return builtinCall(mod, scope, rl, node),
274280 .call => return callExpr(mod, scope, rl, node),
275281 .@"unreachable" => return unreach(mod, scope, node),
......@@ -285,7 +291,22 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
285291 .null_literal => return rvalue(mod, scope, rl, try nullLiteral(mod, scope, node)),
286292 .optional_type => return rvalue(mod, scope, rl, try optionalType(mod, scope, node)),
287293 .unwrap_optional => return unwrapOptional(mod, scope, rl, node),
288 .block => return rvalueVoid(mod, scope, rl, node, try blockExpr(mod, scope, node)),
294
295 .block_two, .block_two_semicolon => {
296 const statements = [2]ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs };
297 if (node_datas[node].lhs == 0) {
298 return blockExpr(mod, scope, rl, node, statements[0..0]);
299 } else if (node_datas[node].rhs == 0) {
300 return blockExpr(mod, scope, rl, node, statements[0..1]);
301 } else {
302 return blockExpr(mod, scope, rl, node, statements[0..2]);
303 }
304 },
305 .block, .block_semicolon => {
306 const statements = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs];
307 return blockExpr(mod, scope, rl, node, statements);
308 },
309
289310 .labeled_block => return labeledBlockExpr(mod, scope, rl, node, .block),
290311 .@"break" => return rvalue(mod, scope, rl, try breakExpr(mod, scope, node)),
291312 .@"continue" => return rvalue(mod, scope, rl, try continueExpr(mod, scope, node)),
......@@ -293,7 +314,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
293314 .array_type => return rvalue(mod, scope, rl, try arrayType(mod, scope, node)),
294315 .array_type_sentinel => return rvalue(mod, scope, rl, try arrayTypeSentinel(mod, scope, node)),
295316 .enum_literal => return rvalue(mod, scope, rl, try enumLiteral(mod, scope, node)),
296 .MultilineStringLiteral => return rvalue(mod, scope, rl, try multilineStrLiteral(mod, scope, node)),
297317 .char_literal => return rvalue(mod, scope, rl, try charLiteral(mod, scope, node)),
298318 .slice_type => return rvalue(mod, scope, rl, try sliceType(mod, scope, node)),
299319 .error_union => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node, .error_union_type)),
......@@ -343,10 +363,17 @@ pub fn comptimeExpr(
343363 return expr(mod, parent_scope, rl, node);
344364 }
345365
366 const tree = parent_scope.tree();
367 const main_tokens = tree.nodes.items(.main_token);
368 const token_tags = tree.tokens.items(.tag);
369
346370 // Optimization for labeled blocks: don't need to have 2 layers of blocks,
347371 // we can reuse the existing one.
348 if (node.castTag(.labeled_block)) |block_node| {
349 return labeledBlockExpr(mod, parent_scope, rl, block_node, .block_comptime);
372 const lbrace = main_tokens[node];
373 if (token_tags[lbrace - 1] == .colon and
374 token_tags[lbrace - 2] == .identifier)
375 {
376 return labeledBlockExpr(mod, parent_scope, rl, node, .block_comptime);
350377 }
351378
352379 // Make a scope to collect generated instructions in the sub-expression.
......@@ -363,11 +390,7 @@ pub fn comptimeExpr(
363390 // instruction is the block's result value.
364391 _ = try expr(mod, &block_scope.base, rl, node);
365392
366 const tree = parent_scope.tree();
367 const node_datas = tree.nodes.items(.data);
368 const main_tokens = tree.nodes.items(.main_token);
369 const src = tree.token_locs[node.firstToken()].start;
370
393 const src = token_starts[tree.firstToken(node)];
371394 const block = try addZIRInstBlock(mod, parent_scope, src, .block_comptime_flat, .{
372395 .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items),
373396 });
......@@ -375,15 +398,13 @@ pub fn comptimeExpr(
375398 return &block.base;
376399}
377400
378fn breakExpr(
379 mod: *Module,
380 parent_scope: *Scope,
381 node: *ast.Node.ControlFlowExpression,
382) InnerError!*zir.Inst {
401fn breakExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst {
383402 const tree = parent_scope.tree();
384403 const node_datas = tree.nodes.items(.data);
385404 const main_tokens = tree.nodes.items(.main_token);
386 const src = tree.token_locs[node.ltoken].start;
405 const src = token_starts[main_tokens[node]];
406 const break_label = node_datas[node].lhs;
407 const rhs = node_datas[node].rhs;
387408
388409 // Look for the label in the scope.
389410 var scope = parent_scope;
......@@ -393,7 +414,7 @@ fn breakExpr(
393414 const gen_zir = scope.cast(Scope.GenZIR).?;
394415
395416 const block_inst = blk: {
396 if (node.getLabel()) |break_label| {
417 if (break_label != 0) {
397418 if (gen_zir.label) |*label| {
398419 if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) {
399420 label.used = true;
......@@ -407,11 +428,11 @@ fn breakExpr(
407428 continue;
408429 };
409430
410 const rhs = node.getRHS() orelse {
431 if (rhs == 0) {
411432 return addZirInstTag(mod, parent_scope, src, .break_void, .{
412433 .block = block_inst,
413434 });
414 };
435 }
415436 gen_zir.break_count += 1;
416437 const prev_rvalue_rl_count = gen_zir.rvalue_rl_count;
417438 const operand = try expr(mod, parent_scope, gen_zir.break_result_loc, rhs);
......@@ -435,7 +456,7 @@ fn breakExpr(
435456 },
436457 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,
437458 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,
438 else => if (node.getLabel()) |break_label| {
459 else => if (break_label != 0) {
439460 const label_name = try mod.identifierTokenString(parent_scope, break_label);
440461 return mod.failTok(parent_scope, break_label, "label not found: '{s}'", .{label_name});
441462 } else {
......@@ -445,11 +466,12 @@ fn breakExpr(
445466 }
446467}
447468
448fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowExpression) InnerError!*zir.Inst {
469fn continueExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst {
449470 const tree = parent_scope.tree();
450471 const node_datas = tree.nodes.items(.data);
451472 const main_tokens = tree.nodes.items(.main_token);
452 const src = tree.token_locs[node.ltoken].start;
473 const src = token_starts[main_tokens[node]];
474 const break_label = node_datas[node].lhs;
453475
454476 // Look for the label in the scope.
455477 var scope = parent_scope;
......@@ -461,7 +483,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE
461483 scope = gen_zir.parent;
462484 continue;
463485 };
464 if (node.getLabel()) |break_label| blk: {
486 if (break_label != 0) blk: {
465487 if (gen_zir.label) |*label| {
466488 if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) {
467489 label.used = true;
......@@ -479,7 +501,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE
479501 },
480502 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,
481503 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,
482 else => if (node.getLabel()) |break_label| {
504 else => if (break_label != 0) {
483505 const label_name = try mod.identifierTokenString(parent_scope, break_label);
484506 return mod.failTok(parent_scope, break_label, "label not found: '{s}'", .{label_name});
485507 } else {
......@@ -489,11 +511,18 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE
489511 }
490512}
491513
492pub fn blockExpr(mod: *Module, parent_scope: *Scope, block_node: *ast.Node.block) InnerError!void {
514pub fn blockExpr(
515 mod: *Module,
516 scope: *Scope,
517 rl: ResultLoc,
518 block_node: ast.Node.Index,
519 statements: []const ast.Node.Index,
520) InnerError!void {
493521 const tracy = trace(@src());
494522 defer tracy.end();
495523
496 try blockExprStmts(mod, parent_scope, &block_node.base, block_node.statements());
524 try blockExprStmts(mod, scope, &block_node.base, statements);
525 return rvalueVoid(mod, scope, rl, block_node, {});
497526}
498527
499528fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIndex) !void {
......@@ -508,8 +537,8 @@ fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIn
508537 const tree = parent_scope.tree();
509538 const node_datas = tree.nodes.items(.data);
510539 const main_tokens = tree.nodes.items(.main_token);
511 const label_src = tree.token_locs[label].start;
512 const prev_label_src = tree.token_locs[prev_label.token].start;
540 const label_src = token_starts[label];
541 const prev_label_src = token_starts[prev_label.token];
513542
514543 const label_name = try mod.identifierTokenString(parent_scope, label);
515544 const msg = msg: {
......@@ -556,7 +585,7 @@ fn labeledBlockExpr(
556585 const tree = parent_scope.tree();
557586 const node_datas = tree.nodes.items(.data);
558587 const main_tokens = tree.nodes.items(.main_token);
559 const src = tree.token_locs[block_node.lbrace].start;
588 const src = token_starts[block_node.lbrace];
560589
561590 try checkLabelRedefinition(mod, parent_scope, block_node.label);
562591
......@@ -595,7 +624,7 @@ fn labeledBlockExpr(
595624 try blockExprStmts(mod, &block_scope.base, &block_node.base, block_node.statements());
596625
597626 if (!block_scope.label.?.used) {
598 return mod.fail(parent_scope, tree.token_locs[block_node.label].start, "unused block label", .{});
627 return mod.fail(parent_scope, token_starts[block_node.label], "unused block label", .{});
599628 }
600629
601630 try gen_zir.instructions.append(mod.gpa, &block_inst.base);
......@@ -647,7 +676,7 @@ fn blockExprStmts(
647676
648677 var scope = parent_scope;
649678 for (statements) |statement| {
650 const src = tree.token_locs[statement.firstToken()].start;
679 const src = token_starts[statement.firstToken()];
651680 _ = try addZIRNoOp(mod, scope, src, .dbg_stmt);
652681 switch (statement.tag) {
653682 .var_decl => {
......@@ -694,7 +723,7 @@ fn varDecl(
694723 const tree = scope.tree();
695724 const node_datas = tree.nodes.items(.data);
696725 const main_tokens = tree.nodes.items(.main_token);
697 const name_src = tree.token_locs[node.name_token].start;
726 const name_src = token_starts[node.name_token];
698727 const ident_name = try mod.identifierTokenString(scope, node.name_token);
699728
700729 // Local variables shadowing detection, including function parameters.
......@@ -911,34 +940,46 @@ fn assignOp(
911940 _ = try addZIRBinOp(mod, scope, src, .store, lhs_ptr, result);
912941}
913942
914fn boolNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst {
943fn boolNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst {
915944 const tree = scope.tree();
916 const src = tree.token_locs[node.op_token].start;
945 const node_datas = tree.nodes.items(.data);
946 const main_tokens = tree.nodes.items(.main_token);
947
948 const src = token_starts[main_tokens[node]];
917949 const bool_type = try addZIRInstConst(mod, scope, src, .{
918950 .ty = Type.initTag(.type),
919951 .val = Value.initTag(.bool_type),
920952 });
921 const operand = try expr(mod, scope, .{ .ty = bool_type }, node.rhs);
953 const operand = try expr(mod, scope, .{ .ty = bool_type }, node_datas[node].lhs);
922954 return addZIRUnOp(mod, scope, src, .bool_not, operand);
923955}
924956
925fn bitNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst {
957fn bitNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst {
926958 const tree = scope.tree();
927 const src = tree.token_locs[node.op_token].start;
928 const operand = try expr(mod, scope, .none, node.rhs);
959 const node_datas = tree.nodes.items(.data);
960 const main_tokens = tree.nodes.items(.main_token);
961
962 const src = token_starts[main_tokens[node]];
963 const operand = try expr(mod, scope, .none, node_datas[node].lhs);
929964 return addZIRUnOp(mod, scope, src, .bit_not, operand);
930965}
931966
932fn negation(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp, op_inst_tag: zir.Inst.Tag) InnerError!*zir.Inst {
967fn negation(
968 mod: *Module,
969 scope: *Scope,
970 node: ast.Node.Index,
971 op_inst_tag: zir.Inst.Tag,
972) InnerError!*zir.Inst {
933973 const tree = scope.tree();
934 const src = tree.token_locs[node.op_token].start;
974 const node_datas = tree.nodes.items(.data);
975 const main_tokens = tree.nodes.items(.main_token);
935976
977 const src = token_starts[main_tokens[node]];
936978 const lhs = try addZIRInstConst(mod, scope, src, .{
937979 .ty = Type.initTag(.comptime_int),
938980 .val = Value.initTag(.zero),
939981 });
940 const rhs = try expr(mod, scope, .none, node.rhs);
941
982 const rhs = try expr(mod, scope, .none, node_datas[node].lhs);
942983 return addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs);
943984}
944985
......@@ -948,20 +989,20 @@ fn addressOf(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerE
948989
949990fn optionalType(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst {
950991 const tree = scope.tree();
951 const src = tree.token_locs[node.op_token].start;
992 const src = token_starts[node.op_token];
952993 const operand = try typeExpr(mod, scope, node.rhs);
953994 return addZIRUnOp(mod, scope, src, .optional_type, operand);
954995}
955996
956997fn sliceType(mod: *Module, scope: *Scope, node: *ast.Node.slice_type) InnerError!*zir.Inst {
957998 const tree = scope.tree();
958 const src = tree.token_locs[node.op_token].start;
999 const src = token_starts[node.op_token];
9591000 return ptrSliceType(mod, scope, src, &node.ptr_info, node.rhs, .Slice);
9601001}
9611002
9621003fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir.Inst {
9631004 const tree = scope.tree();
964 const src = tree.token_locs[node.op_token].start;
1005 const src = token_starts[node.op_token];
9651006 return ptrSliceType(mod, scope, src, &node.ptr_info, node.rhs, switch (tree.token_ids[node.op_token]) {
9661007 .Asterisk, .AsteriskAsterisk => .One,
9671008 // TODO stage1 type inference bug
......@@ -1018,7 +1059,7 @@ fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo,
10181059
10191060fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.array_type) !*zir.Inst {
10201061 const tree = scope.tree();
1021 const src = tree.token_locs[node.op_token].start;
1062 const src = token_starts[node.op_token];
10221063 const usize_type = try addZIRInstConst(mod, scope, src, .{
10231064 .ty = Type.initTag(.type),
10241065 .val = Value.initTag(.usize_type),
......@@ -1033,7 +1074,7 @@ fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.array_type) !*zir.Inst
10331074
10341075fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.array_type_sentinel) !*zir.Inst {
10351076 const tree = scope.tree();
1036 const src = tree.token_locs[node.op_token].start;
1077 const src = token_starts[node.op_token];
10371078 const usize_type = try addZIRInstConst(mod, scope, src, .{
10381079 .ty = Type.initTag(.type),
10391080 .val = Value.initTag(.usize_type),
......@@ -1054,7 +1095,7 @@ fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.array_type_sen
10541095
10551096fn anyFrameType(mod: *Module, scope: *Scope, node: *ast.Node.anyframe_type) InnerError!*zir.Inst {
10561097 const tree = scope.tree();
1057 const src = tree.token_locs[node.anyframe_token].start;
1098 const src = token_starts[node.anyframe_token];
10581099 if (node.result) |some| {
10591100 const return_type = try typeExpr(mod, scope, some.return_type);
10601101 return addZIRUnOp(mod, scope, src, .anyframe_type, return_type);
......@@ -1068,7 +1109,7 @@ fn anyFrameType(mod: *Module, scope: *Scope, node: *ast.Node.anyframe_type) Inne
10681109
10691110fn typeInixOp(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp, op_inst_tag: zir.Inst.Tag) InnerError!*zir.Inst {
10701111 const tree = scope.tree();
1071 const src = tree.token_locs[node.op_token].start;
1112 const src = token_starts[node.op_token];
10721113 const error_set = try typeExpr(mod, scope, node.lhs);
10731114 const payload = try typeExpr(mod, scope, node.rhs);
10741115 return addZIRBinOp(mod, scope, src, op_inst_tag, error_set, payload);
......@@ -1076,7 +1117,7 @@ fn typeInixOp(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp, op_ins
10761117
10771118fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.enum_literal) !*zir.Inst {
10781119 const tree = scope.tree();
1079 const src = tree.token_locs[node.name].start;
1120 const src = token_starts[node.name];
10801121 const name = try mod.identifierTokenString(scope, node.name);
10811122
10821123 return addZIRInst(mod, scope, src, zir.Inst.EnumLiteral, .{ .name = name }, .{});
......@@ -1084,7 +1125,7 @@ fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.enum_literal) !*zir.
10841125
10851126fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {
10861127 const tree = scope.tree();
1087 const src = tree.token_locs[node.rtoken].start;
1128 const src = token_starts[node.rtoken];
10881129
10891130 const operand = try expr(mod, scope, rl, node.lhs);
10901131 const op: zir.Inst.Tag = switch (rl) {
......@@ -1100,7 +1141,7 @@ fn containerField(
11001141 node: *ast.Node.ContainerField,
11011142) InnerError!*zir.Inst {
11021143 const tree = scope.tree();
1103 const src = tree.token_locs[node.firstToken()].start;
1144 const src = token_starts[tree.firstToken(node)];
11041145 const name = try mod.identifierTokenString(scope, node.name_token);
11051146
11061147 if (node.comptime_token == null and node.value_expr == null and node.align_expr == null) {
......@@ -1133,7 +1174,7 @@ fn containerField(
11331174
11341175fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.ContainerDecl) InnerError!*zir.Inst {
11351176 const tree = scope.tree();
1136 const src = tree.token_locs[node.kind_token].start;
1177 const src = token_starts[node.kind_token];
11371178
11381179 var gen_scope: Scope.GenZIR = .{
11391180 .parent = scope,
......@@ -1278,7 +1319,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
12781319
12791320fn errorSetDecl(mod: *Module, scope: *Scope, node: *ast.Node.error_set_decl) InnerError!*zir.Inst {
12801321 const tree = scope.tree();
1281 const src = tree.token_locs[node.error_token].start;
1322 const src = token_starts[node.error_token];
12821323 const decls = node.decls();
12831324 const fields = try scope.arena().alloc([]const u8, decls.len);
12841325
......@@ -1292,7 +1333,7 @@ fn errorSetDecl(mod: *Module, scope: *Scope, node: *ast.Node.error_set_decl) Inn
12921333
12931334fn errorType(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst {
12941335 const tree = scope.tree();
1295 const src = tree.token_locs[node.token].start;
1336 const src = token_starts[node.token];
12961337 return addZIRInstConst(mod, scope, src, .{
12971338 .ty = Type.initTag(.type),
12981339 .val = Value.initTag(.anyerror_type),
......@@ -1370,7 +1411,7 @@ fn orelseCatchExpr(
13701411 payload_node: ?*ast.Node,
13711412) InnerError!*zir.Inst {
13721413 const tree = scope.tree();
1373 const src = tree.token_locs[op_token].start;
1414 const src = token_starts[op_token];
13741415
13751416 var block_scope: Scope.GenZIR = .{
13761417 .parent = scope,
......@@ -1544,7 +1585,7 @@ fn tokenIdentEql(mod: *Module, scope: *Scope, token1: ast.TokenIndex, token2: as
15441585
15451586pub fn field(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleInfixOp) InnerError!*zir.Inst {
15461587 const tree = scope.tree();
1547 const src = tree.token_locs[node.op_token].start;
1588 const src = token_starts[node.op_token];
15481589 // TODO custom AST node for field access so that we don't have to go through a node cast here
15491590 const field_name = try mod.identifierTokenString(scope, node.rhs.castTag(.identifier).?.token);
15501591 if (rl == .ref) {
......@@ -1568,7 +1609,7 @@ fn namedField(
15681609 try ensureBuiltinParamCount(mod, scope, call, 2);
15691610
15701611 const tree = scope.tree();
1571 const src = tree.token_locs[call.builtin_token].start;
1612 const src = token_starts[call.builtin_token];
15721613 const params = call.params();
15731614
15741615 const string_type = try addZIRInstConst(mod, scope, src, .{
......@@ -1591,7 +1632,7 @@ fn namedField(
15911632
15921633fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.array_access) InnerError!*zir.Inst {
15931634 const tree = scope.tree();
1594 const src = tree.token_locs[node.rtoken].start;
1635 const src = token_starts[node.rtoken];
15951636 const usize_type = try addZIRInstConst(mod, scope, src, .{
15961637 .ty = Type.initTag(.type),
15971638 .val = Value.initTag(.usize_type),
......@@ -1612,7 +1653,7 @@ fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.array
16121653
16131654fn sliceExpr(mod: *Module, scope: *Scope, node: *ast.Node.slice) InnerError!*zir.Inst {
16141655 const tree = scope.tree();
1615 const src = tree.token_locs[node.rtoken].start;
1656 const src = token_starts[node.rtoken];
16161657
16171658 const usize_type = try addZIRInstConst(mod, scope, src, .{
16181659 .ty = Type.initTag(.type),
......@@ -1642,7 +1683,7 @@ fn sliceExpr(mod: *Module, scope: *Scope, node: *ast.Node.slice) InnerError!*zir
16421683
16431684fn deref(mod: *Module, scope: *Scope, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {
16441685 const tree = scope.tree();
1645 const src = tree.token_locs[node.rtoken].start;
1686 const src = token_starts[node.rtoken];
16461687 const lhs = try expr(mod, scope, .none, node.lhs);
16471688 return addZIRUnOp(mod, scope, src, .deref, lhs);
16481689}
......@@ -1669,13 +1710,14 @@ fn boolBinOp(
16691710 mod: *Module,
16701711 scope: *Scope,
16711712 rl: ResultLoc,
1672 infix_node: *ast.Node.SimpleInfixOp,
1713 infix_node: ast.Node.Index,
1714 is_bool_and: bool,
16731715) InnerError!*zir.Inst {
16741716 const tree = scope.tree();
16751717 const node_datas = tree.nodes.items(.data);
16761718 const main_tokens = tree.nodes.items(.main_token);
16771719
1678 const src = tree.token_locs[infix_node.op_token].start;
1720 const src = token_starts[main_tokens[infix_node]];
16791721 const bool_type = try addZIRInstConst(mod, scope, src, .{
16801722 .ty = Type.initTag(.type),
16811723 .val = Value.initTag(.bool_type),
......@@ -1690,7 +1732,7 @@ fn boolBinOp(
16901732 };
16911733 defer block_scope.instructions.deinit(mod.gpa);
16921734
1693 const lhs = try expr(mod, scope, .{ .ty = bool_type }, infix_node.lhs);
1735 const lhs = try expr(mod, scope, .{ .ty = bool_type }, node_datas[infix_node].lhs);
16941736 const condbr = try addZIRInstSpecial(mod, &block_scope.base, src, zir.Inst.CondBr, .{
16951737 .condition = lhs,
16961738 .then_body = undefined, // populated below
......@@ -1710,7 +1752,7 @@ fn boolBinOp(
17101752 };
17111753 defer rhs_scope.instructions.deinit(mod.gpa);
17121754
1713 const rhs = try expr(mod, &rhs_scope.base, .{ .ty = bool_type }, infix_node.rhs);
1755 const rhs = try expr(mod, &rhs_scope.base, .{ .ty = bool_type }, node_datas[infix_node].rhs);
17141756 _ = try addZIRInst(mod, &rhs_scope.base, src, zir.Inst.Break, .{
17151757 .block = block,
17161758 .operand = rhs,
......@@ -1725,7 +1767,6 @@ fn boolBinOp(
17251767 };
17261768 defer const_scope.instructions.deinit(mod.gpa);
17271769
1728 const is_bool_and = infix_node.base.tag == .bool_and;
17291770 _ = try addZIRInst(mod, &const_scope.base, src, zir.Inst.Break, .{
17301771 .block = block,
17311772 .operand = try addZIRInstConst(mod, &const_scope.base, src, .{
......@@ -1843,7 +1884,7 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.@"if")
18431884 const tree = scope.tree();
18441885 const node_datas = tree.nodes.items(.data);
18451886 const main_tokens = tree.nodes.items(.main_token);
1846 const if_src = tree.token_locs[if_node.if_token].start;
1887 const if_src = token_starts[if_node.if_token];
18471888 const cond = try cond_kind.cond(mod, &block_scope, if_src, if_node.condition);
18481889
18491890 const condbr = try addZIRInstSpecial(mod, &block_scope.base, if_src, zir.Inst.CondBr, .{
......@@ -1856,7 +1897,7 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.@"if")
18561897 .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items),
18571898 });
18581899
1859 const then_src = tree.token_locs[if_node.body.lastToken()].start;
1900 const then_src = token_starts[if_node.body.lastToken()];
18601901 var then_scope: Scope.GenZIR = .{
18611902 .parent = scope,
18621903 .decl = block_scope.decl,
......@@ -1887,14 +1928,14 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.@"if")
18871928 var else_src: usize = undefined;
18881929 var else_sub_scope: *Module.Scope = undefined;
18891930 const else_result: ?*zir.Inst = if (if_node.@"else") |else_node| blk: {
1890 else_src = tree.token_locs[else_node.body.lastToken()].start;
1931 else_src = token_starts[else_node.body.lastToken()];
18911932 // declare payload to the then_scope
18921933 else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload);
18931934
18941935 block_scope.break_count += 1;
18951936 break :blk try expr(mod, else_sub_scope, block_scope.break_result_loc, else_node.body);
18961937 } else blk: {
1897 else_src = tree.token_locs[if_node.lastToken()].start;
1938 else_src = token_starts[if_node.lastToken()];
18981939 else_sub_scope = &else_scope.base;
18991940 break :blk null;
19001941 };
......@@ -1981,7 +2022,7 @@ fn whileExpr(
19812022 const tree = scope.tree();
19822023 const node_datas = tree.nodes.items(.data);
19832024 const main_tokens = tree.nodes.items(.main_token);
1984 const while_src = tree.token_locs[while_node.while_token].start;
2025 const while_src = token_starts[while_node.while_token];
19852026 const void_type = try addZIRInstConst(mod, scope, while_src, .{
19862027 .ty = Type.initTag(.type),
19872028 .val = Value.initTag(.void_type),
......@@ -2028,7 +2069,7 @@ fn whileExpr(
20282069 });
20292070 }
20302071
2031 const then_src = tree.token_locs[while_node.body.lastToken()].start;
2072 const then_src = token_starts[while_node.body.lastToken()];
20322073 var then_scope: Scope.GenZIR = .{
20332074 .parent = &continue_scope.base,
20342075 .decl = continue_scope.decl,
......@@ -2055,19 +2096,19 @@ fn whileExpr(
20552096
20562097 var else_src: usize = undefined;
20572098 const else_result: ?*zir.Inst = if (while_node.@"else") |else_node| blk: {
2058 else_src = tree.token_locs[else_node.body.lastToken()].start;
2099 else_src = token_starts[else_node.body.lastToken()];
20592100 // declare payload to the then_scope
20602101 const else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload);
20612102
20622103 loop_scope.break_count += 1;
20632104 break :blk try expr(mod, else_sub_scope, loop_scope.break_result_loc, else_node.body);
20642105 } else blk: {
2065 else_src = tree.token_locs[while_node.lastToken()].start;
2106 else_src = token_starts[while_node.lastToken()];
20662107 break :blk null;
20672108 };
20682109 if (loop_scope.label) |some| {
20692110 if (!some.used) {
2070 return mod.fail(scope, tree.token_locs[some.token].start, "unused while label", .{});
2111 return mod.fail(scope, token_starts[some.token], "unused while label", .{});
20712112 }
20722113 }
20732114 return finishThenElseBlock(
......@@ -2105,7 +2146,7 @@ fn forExpr(
21052146 const tree = scope.tree();
21062147 const node_datas = tree.nodes.items(.data);
21072148 const main_tokens = tree.nodes.items(.main_token);
2108 const for_src = tree.token_locs[for_node.for_token].start;
2149 const for_src = token_starts[for_node.for_token];
21092150 const index_ptr = blk: {
21102151 const usize_type = try addZIRInstConst(mod, scope, for_src, .{
21112152 .ty = Type.initTag(.type),
......@@ -2121,7 +2162,7 @@ fn forExpr(
21212162 break :blk index_ptr;
21222163 };
21232164 const array_ptr = try expr(mod, scope, .ref, for_node.array_expr);
2124 const cond_src = tree.token_locs[for_node.array_expr.firstToken()].start;
2165 const cond_src = token_starts[for_node.array_expr.firstToken()];
21252166 const len = try addZIRUnOp(mod, scope, cond_src, .indexable_ptr_len, array_ptr);
21262167
21272168 var loop_scope: Scope.GenZIR = .{
......@@ -2191,7 +2232,7 @@ fn forExpr(
21912232 }
21922233
21932234 // while body
2194 const then_src = tree.token_locs[for_node.body.lastToken()].start;
2235 const then_src = token_starts[for_node.body.lastToken()];
21952236 var then_scope: Scope.GenZIR = .{
21962237 .parent = &cond_scope.base,
21972238 .decl = cond_scope.decl,
......@@ -2215,7 +2256,7 @@ fn forExpr(
22152256 const index_symbol_node = payload.index_symbol orelse
22162257 break :blk &then_scope.base;
22172258
2218 const index_name = tree.tokenSlice(index_symbol_node.firstToken());
2259 const index_name = tree.tokenSlice(tree.firstToken(index_symbol_node));
22192260 if (mem.eql(u8, index_name, "_")) {
22202261 break :blk &then_scope.base;
22212262 }
......@@ -2244,16 +2285,16 @@ fn forExpr(
22442285
22452286 var else_src: usize = undefined;
22462287 const else_result: ?*zir.Inst = if (for_node.@"else") |else_node| blk: {
2247 else_src = tree.token_locs[else_node.body.lastToken()].start;
2288 else_src = token_starts[else_node.body.lastToken()];
22482289 loop_scope.break_count += 1;
22492290 break :blk try expr(mod, &else_scope.base, loop_scope.break_result_loc, else_node.body);
22502291 } else blk: {
2251 else_src = tree.token_locs[for_node.lastToken()].start;
2292 else_src = token_starts[for_node.lastToken()];
22522293 break :blk null;
22532294 };
22542295 if (loop_scope.label) |some| {
22552296 if (!some.used) {
2256 return mod.fail(scope, tree.token_locs[some.token].start, "unused for label", .{});
2297 return mod.fail(scope, token_starts[some.token], "unused for label", .{});
22572298 }
22582299 }
22592300 return finishThenElseBlock(
......@@ -2299,7 +2340,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node
22992340 const tree = scope.tree();
23002341 const node_datas = tree.nodes.items(.data);
23012342 const main_tokens = tree.nodes.items(.main_token);
2302 const switch_src = tree.token_locs[switch_node.switch_token].start;
2343 const switch_src = token_starts[switch_node.switch_token];
23032344 const use_ref = switchCaseUsesRef(switch_node);
23042345
23052346 var block_scope: Scope.GenZIR = .{
......@@ -2322,7 +2363,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node
23222363 var simple_case_count: usize = 0;
23232364 for (switch_node.cases()) |uncasted_case| {
23242365 const case = uncasted_case.castTag(.switch_case).?;
2325 const case_src = tree.token_locs[case.firstToken()].start;
2366 const case_src = token_starts[case.firstToken()];
23262367 assert(case.items_len != 0);
23272368
23282369 // Check for else/_ prong, those are handled last.
......@@ -2389,7 +2430,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node
23892430 if (getRangeNode(item)) |range| {
23902431 const start = try comptimeExpr(mod, &block_scope.base, .none, range.lhs);
23912432 const end = try comptimeExpr(mod, &block_scope.base, .none, range.rhs);
2392 const range_src = tree.token_locs[range.op_token].start;
2433 const range_src = token_starts[range.op_token];
23932434 const range_inst = try addZIRBinOp(mod, &block_scope.base, range_src, .switch_range, start, end);
23942435 try items.append(range_inst);
23952436 } else {
......@@ -2447,7 +2488,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node
24472488 var case_index: usize = 0;
24482489 for (switch_node.cases()) |uncasted_case| {
24492490 const case = uncasted_case.castTag(.switch_case).?;
2450 const case_src = tree.token_locs[case.firstToken()].start;
2491 const case_src = token_starts[case.firstToken()];
24512492 // reset without freeing to reduce allocations.
24522493 case_scope.instructions.items.len = 0;
24532494
......@@ -2485,7 +2526,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node
24852526 var any_ok: ?*zir.Inst = null;
24862527 for (case.items()) |item| {
24872528 if (getRangeNode(item)) |range| {
2488 const range_src = tree.token_locs[range.op_token].start;
2529 const range_src = token_starts[range.op_token];
24892530 const range_inst = items.items[items_index].castTag(.switch_range).?;
24902531 items_index += 1;
24912532
......@@ -2565,7 +2606,7 @@ fn switchCaseExpr(
25652606 const tree = scope.tree();
25662607 const node_datas = tree.nodes.items(.data);
25672608 const main_tokens = tree.nodes.items(.main_token);
2568 const case_src = tree.token_locs[case.firstToken()].start;
2609 const case_src = token_starts[case.firstToken()];
25692610 const sub_scope = blk: {
25702611 const uncasted_payload = case.payload orelse break :blk scope;
25712612 const payload = uncasted_payload.castTag(.PointerPayload).?;
......@@ -2593,7 +2634,7 @@ fn ret(mod: *Module, scope: *Scope, cfe: *ast.Node.ControlFlowExpression) InnerE
25932634 const tree = scope.tree();
25942635 const node_datas = tree.nodes.items(.data);
25952636 const main_tokens = tree.nodes.items(.main_token);
2596 const src = tree.token_locs[cfe.ltoken].start;
2637 const src = token_starts[cfe.ltoken];
25972638 if (cfe.getRHS()) |rhs_node| {
25982639 if (nodeMayNeedMemoryLocation(rhs_node, scope)) {
25992640 const ret_ptr = try addZIRNoOp(mod, scope, src, .ret_ptr);
......@@ -2609,17 +2650,24 @@ fn ret(mod: *Module, scope: *Scope, cfe: *ast.Node.ControlFlowExpression) InnerE
26092650 }
26102651}
26112652
2612fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneToken) InnerError!*zir.Inst {
2653fn identifier(
2654 mod: *Module,
2655 scope: *Scope,
2656 rl: ResultLoc,
2657 ident: ast.Node.Index,
2658) InnerError!*zir.Inst {
26132659 const tracy = trace(@src());
26142660 defer tracy.end();
26152661
26162662 const tree = scope.tree();
26172663 const node_datas = tree.nodes.items(.data);
26182664 const main_tokens = tree.nodes.items(.main_token);
2619 const ident_name = try mod.identifierTokenString(scope, ident.token);
2620 const src = tree.token_locs[ident.token].start;
2665
2666 const ident_token = main_tokens[ident];
2667 const ident_name = try mod.identifierTokenString(scope, ident_token);
2668 const src = token_starts[ident_token];
26212669 if (mem.eql(u8, ident_name, "_")) {
2622 return mod.failNode(scope, &ident.base, "TODO implement '_' identifier", .{});
2670 return mod.failNode(scope, ident, "TODO implement '_' identifier", .{});
26232671 }
26242672
26252673 if (getSimplePrimitiveValue(ident_name)) |typed_value| {
......@@ -2634,7 +2682,7 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo
26342682 const bit_count = std.fmt.parseInt(u16, ident_name[1..], 10) catch |err| switch (err) {
26352683 error.Overflow => return mod.failNode(
26362684 scope,
2637 &ident.base,
2685 ident,
26382686 "primitive integer type '{s}' exceeds maximum bit width of 65535",
26392687 .{ident_name},
26402688 ),
......@@ -2698,64 +2746,91 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo
26982746 }
26992747 }
27002748
2701 return mod.failNode(scope, &ident.base, "use of undeclared identifier '{s}'", .{ident_name});
2749 return mod.failNode(scope, ident, "use of undeclared identifier '{s}'", .{ident_name});
27022750}
27032751
2704fn stringLiteral(mod: *Module, scope: *Scope, str_lit: *ast.Node.OneToken) InnerError!*zir.Inst {
2752fn stringLiteral(
2753 mod: *Module,
2754 scope: *Scope,
2755 rl: ResultLoc,
2756 str_lit: ast.Node.Index,
2757) InnerError!*zir.Inst {
27052758 const tree = scope.tree();
27062759 const node_datas = tree.nodes.items(.data);
27072760 const main_tokens = tree.nodes.items(.main_token);
2708 const unparsed_bytes = tree.tokenSlice(str_lit.token);
2761
2762 const str_lit_token = main_tokens[str_lit];
2763 const unparsed_bytes = tree.tokenSlice(str_lit_token);
27092764 const arena = scope.arena();
27102765
27112766 var bad_index: usize = undefined;
27122767 const bytes = std.zig.parseStringLiteral(arena, unparsed_bytes, &bad_index) catch |err| switch (err) {
27132768 error.InvalidCharacter => {
27142769 const bad_byte = unparsed_bytes[bad_index];
2715 const src = tree.token_locs[str_lit.token].start;
2770 const src = token_starts[str_lit_token];
27162771 return mod.fail(scope, src + bad_index, "invalid string literal character: '{c}'\n", .{bad_byte});
27172772 },
27182773 else => |e| return e,
27192774 };
27202775
2721 const src = tree.token_locs[str_lit.token].start;
2722 return addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{});
2776 const src = token_starts[str_lit_token];
2777 const str_inst = try addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{});
2778 return rvalue(mod, scope, rl, str_inst);
27232779}
27242780
2725fn multilineStrLiteral(mod: *Module, scope: *Scope, node: *ast.Node.MultilineStringLiteral) !*zir.Inst {
2781fn multilineStringLiteral(
2782 mod: *Module,
2783 scope: *Scope,
2784 rl: ResultLoc,
2785 str_lit: ast.Node.Index,
2786) InnerError!*zir.Inst {
27262787 const tree = scope.tree();
27272788 const node_datas = tree.nodes.items(.data);
27282789 const main_tokens = tree.nodes.items(.main_token);
2729 const lines = node.linesConst();
2730 const src = tree.token_locs[lines[0]].start;
27312790
2732 // line lengths and new lines
2733 var len = lines.len - 1;
2734 for (lines) |line| {
2735 // 2 for the '//' + 1 for '\n'
2736 len += tree.tokenSlice(line).len - 3;
2737 }
2791 const start = node_datas[node].lhs;
2792 const end = node_datas[node].rhs;
27382793
2739 const bytes = try scope.arena().alloc(u8, len);
2740 var i: usize = 0;
2741 for (lines) |line, line_i| {
2742 if (line_i != 0) {
2743 bytes[i] = '\n';
2744 i += 1;
2794 // Count the number of bytes to allocate.
2795 const len: usize = len: {
2796 var tok_i = start;
2797 var len: usize = 0;
2798 while (tok_i <= end) : (tok_i += 1) {
2799 // 2 for the '//' + 1 for '\n'
2800 len += tree.tokenSlice(tok_i).len - 3;
27452801 }
2746 const slice = tree.tokenSlice(line);
2747 mem.copy(u8, bytes[i..], slice[2 .. slice.len - 1]);
2748 i += slice.len - 3;
2749 }
2750
2751 return addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{});
2802 break :len len;
2803 };
2804 const bytes = try scope.arena().alloc(u8, len);
2805 // First line: do not append a newline.
2806 var byte_i: usize = 0;
2807 var tok_i = start;
2808 {
2809 const slice = tree.tokenSlice(tok_i);
2810 const line_bytes = slice[2 .. slice.len - 1];
2811 mem.copy(u8, bytes[byte_i..], line_bytes);
2812 byte_i += line_bytes.len;
2813 tok_i += 1;
2814 }
2815 // Following lines: each line prepends a newline.
2816 while (tok_i <= end) : (tok_i += 1) {
2817 bytes[byte_i] = '\n';
2818 byte_i += 1;
2819 const slice = tree.tokenSlice(tok_i);
2820 const line_bytes = slice[2 .. slice.len - 1];
2821 mem.copy(u8, bytes[byte_i..], line_bytes);
2822 byte_i += line_bytes.len;
2823 }
2824 const src = token_starts[start];
2825 const str_inst = try addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{});
2826 return rvalue(mod, scope, rl, str_inst);
27522827}
27532828
27542829fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst {
27552830 const tree = scope.tree();
27562831 const node_datas = tree.nodes.items(.data);
27572832 const main_tokens = tree.nodes.items(.main_token);
2758 const src = tree.token_locs[node.token].start;
2833 const src = token_starts[node.token];
27592834 const slice = tree.tokenSlice(node.token);
27602835
27612836 var bad_index: usize = undefined;
......@@ -2772,13 +2847,19 @@ fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst
27722847 });
27732848}
27742849
2775fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) InnerError!*zir.Inst {
2850fn integerLiteral(
2851 mod: *Module,
2852 scope: *Scope,
2853 rl: ResultLoc,
2854 int_lit: ast.Node.Index,
2855) InnerError!*zir.Inst {
27762856 const arena = scope.arena();
27772857 const tree = scope.tree();
2778 const node_datas = tree.nodes.items(.data);
27792858 const main_tokens = tree.nodes.items(.main_token);
2780 const prefixed_bytes = tree.tokenSlice(int_lit.token);
2781 const base = if (mem.startsWith(u8, prefixed_bytes, "0x"))
2859
2860 const int_token = main_tokens[int_lit];
2861 const prefixed_bytes = tree.tokenSlice(int_token);
2862 const base: u8 = if (mem.startsWith(u8, prefixed_bytes, "0x"))
27822863 16
27832864 else if (mem.startsWith(u8, prefixed_bytes, "0o"))
27842865 8
......@@ -2793,13 +2874,14 @@ fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) Inne
27932874 prefixed_bytes[2..];
27942875
27952876 if (std.fmt.parseInt(u64, bytes, base)) |small_int| {
2796 const src = tree.token_locs[int_lit.token].start;
2797 return addZIRInstConst(mod, scope, src, .{
2877 const src = token_starts[int_token];
2878 const result = try addZIRInstConst(mod, scope, src, .{
27982879 .ty = Type.initTag(.comptime_int),
27992880 .val = try Value.Tag.int_u64.create(arena, small_int),
28002881 });
2882 return rvalue(mod, scope, rl, result);
28012883 } else |err| {
2802 return mod.failTok(scope, int_lit.token, "TODO implement int literals that don't fit in a u64", .{});
2884 return mod.failTok(scope, int_token, "TODO implement int literals that don't fit in a u64", .{});
28032885 }
28042886}
28052887
......@@ -2816,7 +2898,7 @@ fn floatLiteral(mod: *Module, scope: *Scope, float_lit: *ast.Node.OneToken) Inne
28162898 const float_number = std.fmt.parseFloat(f128, bytes) catch |e| switch (e) {
28172899 error.InvalidCharacter => unreachable, // validated by tokenizer
28182900 };
2819 const src = tree.token_locs[float_lit.token].start;
2901 const src = token_starts[float_lit.token];
28202902 return addZIRInstConst(mod, scope, src, .{
28212903 .ty = Type.initTag(.comptime_float),
28222904 .val = try Value.Tag.float_128.create(arena, float_number),
......@@ -2828,7 +2910,7 @@ fn undefLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerErro
28282910 const tree = scope.tree();
28292911 const node_datas = tree.nodes.items(.data);
28302912 const main_tokens = tree.nodes.items(.main_token);
2831 const src = tree.token_locs[node.token].start;
2913 const src = token_starts[node.token];
28322914 return addZIRInstConst(mod, scope, src, .{
28332915 .ty = Type.initTag(.@"undefined"),
28342916 .val = Value.initTag(.undef),
......@@ -2840,7 +2922,7 @@ fn boolLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError
28402922 const tree = scope.tree();
28412923 const node_datas = tree.nodes.items(.data);
28422924 const main_tokens = tree.nodes.items(.main_token);
2843 const src = tree.token_locs[node.token].start;
2925 const src = token_starts[node.token];
28442926 return addZIRInstConst(mod, scope, src, .{
28452927 .ty = Type.initTag(.bool),
28462928 .val = switch (tree.token_ids[node.token]) {
......@@ -2856,34 +2938,34 @@ fn nullLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError
28562938 const tree = scope.tree();
28572939 const node_datas = tree.nodes.items(.data);
28582940 const main_tokens = tree.nodes.items(.main_token);
2859 const src = tree.token_locs[node.token].start;
2941 const src = token_starts[node.token];
28602942 return addZIRInstConst(mod, scope, src, .{
28612943 .ty = Type.initTag(.@"null"),
28622944 .val = Value.initTag(.null_value),
28632945 });
28642946}
28652947
2866fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.@"asm") InnerError!*zir.Inst {
2867 if (asm_node.outputs.len != 0) {
2868 return mod.failNode(scope, &asm_node.base, "TODO implement asm with an output", .{});
2869 }
2948fn assembly(mod: *Module, scope: *Scope, rl: ResultLoc, full: ast.full.Asm) InnerError!*zir.Inst {
28702949 const arena = scope.arena();
28712950 const tree = scope.tree();
28722951 const node_datas = tree.nodes.items(.data);
28732952 const main_tokens = tree.nodes.items(.main_token);
28742953
2875 const inputs = try arena.alloc(*zir.Inst, asm_node.inputs.len);
2876 const args = try arena.alloc(*zir.Inst, asm_node.inputs.len);
2954 if (full.outputs.len != 0) {
2955 return mod.failTok(scope, full.ast.asm_token, "TODO implement asm with an output", .{});
2956 }
28772957
2878 const src = tree.token_locs[asm_node.asm_token].start;
2958 const inputs = try arena.alloc(*zir.Inst, full.inputs.len);
2959 const args = try arena.alloc(*zir.Inst, full.inputs.len);
28792960
2961 const src = token_starts[full.ast.asm_token];
28802962 const str_type = try addZIRInstConst(mod, scope, src, .{
28812963 .ty = Type.initTag(.type),
28822964 .val = Value.initTag(.const_slice_u8_type),
28832965 });
28842966 const str_type_rl: ResultLoc = .{ .ty = str_type };
28852967
2886 for (asm_node.inputs) |input, i| {
2968 for (full.inputs) |input, i| {
28872969 // TODO semantically analyze constraints
28882970 inputs[i] = try expr(mod, scope, str_type_rl, input.constraint);
28892971 args[i] = try expr(mod, scope, .none, input.expr);
......@@ -2894,15 +2976,15 @@ fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.@"asm") InnerError!
28942976 .val = Value.initTag(.void_type),
28952977 });
28962978 const asm_inst = try addZIRInst(mod, scope, src, zir.Inst.@"asm", .{
2897 .asm_source = try expr(mod, scope, str_type_rl, asm_node.template),
2979 .asm_source = try expr(mod, scope, str_type_rl, full.ast.template),
28982980 .return_type = return_type,
28992981 }, .{
2900 .@"volatile" = asm_node.volatile_token != null,
2982 .@"volatile" = full.volatile_token != null,
29012983 //.clobbers = TODO handle clobbers
29022984 .inputs = inputs,
29032985 .args = args,
29042986 });
2905 return asm_inst;
2987 return rvalue(mod, scope, rl, asm_inst);
29062988}
29072989
29082990fn ensureBuiltinParamCount(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call, count: u32) !void {
......@@ -2924,7 +3006,7 @@ fn simpleCast(
29243006 const tree = scope.tree();
29253007 const node_datas = tree.nodes.items(.data);
29263008 const main_tokens = tree.nodes.items(.main_token);
2927 const src = tree.token_locs[call.builtin_token].start;
3009 const src = token_starts[call.builtin_token];
29283010 const params = call.params();
29293011 const dest_type = try typeExpr(mod, scope, params[0]);
29303012 const rhs = try expr(mod, scope, .none, params[1]);
......@@ -2938,7 +3020,7 @@ fn ptrToInt(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerErro
29383020 const tree = scope.tree();
29393021 const node_datas = tree.nodes.items(.data);
29403022 const main_tokens = tree.nodes.items(.main_token);
2941 const src = tree.token_locs[call.builtin_token].start;
3023 const src = token_starts[call.builtin_token];
29423024 return addZIRUnOp(mod, scope, src, .ptrtoint, operand);
29433025}
29443026
......@@ -2952,7 +3034,7 @@ fn as(
29523034 const tree = scope.tree();
29533035 const node_datas = tree.nodes.items(.data);
29543036 const main_tokens = tree.nodes.items(.main_token);
2955 const src = tree.token_locs[call.builtin_token].start;
3037 const src = token_starts[call.builtin_token];
29563038 const params = call.params();
29573039 const dest_type = try typeExpr(mod, scope, params[0]);
29583040 switch (rl) {
......@@ -3028,7 +3110,7 @@ fn bitCast(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.builtin_c
30283110 const tree = scope.tree();
30293111 const node_datas = tree.nodes.items(.data);
30303112 const main_tokens = tree.nodes.items(.main_token);
3031 const src = tree.token_locs[call.builtin_token].start;
3113 const src = token_starts[call.builtin_token];
30323114 const params = call.params();
30333115 const dest_type = try typeExpr(mod, scope, params[0]);
30343116 switch (rl) {
......@@ -3074,7 +3156,7 @@ fn import(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerError!
30743156 const tree = scope.tree();
30753157 const node_datas = tree.nodes.items(.data);
30763158 const main_tokens = tree.nodes.items(.main_token);
3077 const src = tree.token_locs[call.builtin_token].start;
3159 const src = token_starts[call.builtin_token];
30783160 const params = call.params();
30793161 const target = try expr(mod, scope, .none, params[0]);
30803162 return addZIRUnOp(mod, scope, src, .import, target);
......@@ -3085,7 +3167,7 @@ fn compileError(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) Inner
30853167 const tree = scope.tree();
30863168 const node_datas = tree.nodes.items(.data);
30873169 const main_tokens = tree.nodes.items(.main_token);
3088 const src = tree.token_locs[call.builtin_token].start;
3170 const src = token_starts[call.builtin_token];
30893171 const params = call.params();
30903172 const target = try expr(mod, scope, .none, params[0]);
30913173 return addZIRUnOp(mod, scope, src, .compile_error, target);
......@@ -3096,7 +3178,7 @@ fn setEvalBranchQuota(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call)
30963178 const tree = scope.tree();
30973179 const node_datas = tree.nodes.items(.data);
30983180 const main_tokens = tree.nodes.items(.main_token);
3099 const src = tree.token_locs[call.builtin_token].start;
3181 const src = token_starts[call.builtin_token];
31003182 const params = call.params();
31013183 const u32_type = try addZIRInstConst(mod, scope, src, .{
31023184 .ty = Type.initTag(.type),
......@@ -3111,7 +3193,7 @@ fn typeOf(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.builtin_ca
31113193 const node_datas = tree.nodes.items(.data);
31123194 const main_tokens = tree.nodes.items(.main_token);
31133195 const arena = scope.arena();
3114 const src = tree.token_locs[call.builtin_token].start;
3196 const src = token_starts[call.builtin_token];
31153197 const params = call.params();
31163198 if (params.len < 1) {
31173199 return mod.failTok(scope, call.builtin_token, "expected at least 1 argument, found 0", .{});
......@@ -3129,7 +3211,7 @@ fn compileLog(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerEr
31293211 const node_datas = tree.nodes.items(.data);
31303212 const main_tokens = tree.nodes.items(.main_token);
31313213 const arena = scope.arena();
3132 const src = tree.token_locs[call.builtin_token].start;
3214 const src = token_starts[call.builtin_token];
31333215 const params = call.params();
31343216 var targets = try arena.alloc(*zir.Inst, params.len);
31353217 for (params) |param, param_i|
......@@ -3161,7 +3243,7 @@ fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.built
31613243 } else if (mem.eql(u8, builtin_name, "@TypeOf")) {
31623244 return typeOf(mod, scope, rl, call);
31633245 } else if (mem.eql(u8, builtin_name, "@breakpoint")) {
3164 const src = tree.token_locs[call.builtin_token].start;
3246 const src = token_starts[call.builtin_token];
31653247 return rvalue(mod, scope, rl, try addZIRNoOp(mod, scope, src, .breakpoint));
31663248 } else if (mem.eql(u8, builtin_name, "@import")) {
31673249 return rvalue(mod, scope, rl, try import(mod, scope, call));
......@@ -3187,7 +3269,7 @@ fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.call) In
31873269 const param_nodes = node.params();
31883270 const args = try scope.getGenZIR().arena.alloc(*zir.Inst, param_nodes.len);
31893271 for (param_nodes) |param_node, i| {
3190 const param_src = tree.token_locs[param_node.firstToken()].start;
3272 const param_src = token_starts[tree.firstToken(param_node)];
31913273 const param_type = try addZIRInst(mod, scope, param_src, zir.Inst.ParamType, .{
31923274 .func = lhs,
31933275 .arg_index = i,
......@@ -3195,7 +3277,7 @@ fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.call) In
31953277 args[i] = try expr(mod, scope, .{ .ty = param_type }, param_node);
31963278 }
31973279
3198 const src = tree.token_locs[node.lhs.firstToken()].start;
3280 const src = token_starts[node.lhs.firstToken()];
31993281 const result = try addZIRInst(mod, scope, src, zir.Inst.Call, .{
32003282 .func = lhs,
32013283 .args = args,
......@@ -3208,7 +3290,7 @@ fn unreach(mod: *Module, scope: *Scope, unreach_node: *ast.Node.OneToken) InnerE
32083290 const tree = scope.tree();
32093291 const node_datas = tree.nodes.items(.data);
32103292 const main_tokens = tree.nodes.items(.main_token);
3211 const src = tree.token_locs[unreach_node.token].start;
3293 const src = token_starts[unreach_node.token];
32123294 return addZIRNoOp(mod, scope, src, .unreachable_safe);
32133295}
32143296
......@@ -3528,6 +3610,8 @@ fn rvalue(mod: *Module, scope: *Scope, rl: ResultLoc, result: *zir.Inst) InnerEr
35283610 }
35293611}
35303612
3613/// TODO when reworking ZIR memory layout, make the void value correspond to a hard coded
3614/// index; that way this does not actually need to allocate anything.
35313615fn rvalueVoid(
35323616 mod: *Module,
35333617 scope: *Scope,