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 {...@@ -283,6 +283,7 @@ pub const Tree = struct {
283 .undefined_literal,283 .undefined_literal,
284 .unreachable_literal,284 .unreachable_literal,
285 .string_literal,285 .string_literal,
286 .multiline_string_literal,
286 .grouped_expression,287 .grouped_expression,
287 .builtin_call_two,288 .builtin_call_two,
288 .builtin_call_two_comma,289 .builtin_call_two_comma,
...@@ -593,7 +594,7 @@ pub const Tree = struct {...@@ -593,7 +594,7 @@ pub const Tree = struct {
593 .field_access,594 .field_access,
594 .unwrap_optional,595 .unwrap_optional,
595 .grouped_expression,596 .grouped_expression,
596 .string_literal,597 .multiline_string_literal,
597 .error_set_decl,598 .error_set_decl,
598 .asm_simple,599 .asm_simple,
599 .asm_output,600 .asm_output,
...@@ -614,6 +615,7 @@ pub const Tree = struct {...@@ -614,6 +615,7 @@ pub const Tree = struct {
614 .identifier,615 .identifier,
615 .deref,616 .deref,
616 .enum_literal,617 .enum_literal,
618 .string_literal,
617 => return main_tokens[n] + end_offset,619 => return main_tokens[n] + end_offset,
618620
619 .@"return" => if (datas[n].lhs != 0) {621 .@"return" => if (datas[n].lhs != 0) {
...@@ -2826,11 +2828,14 @@ pub const Node = struct {...@@ -2826,11 +2828,14 @@ pub const Node = struct {
2826 identifier,2828 identifier,
2827 /// lhs is the dot token index, rhs unused, main_token is the identifier.2829 /// lhs is the dot token index, rhs unused, main_token is the identifier.
2828 enum_literal,2830 enum_literal,
2831 /// main_token is the string literal token
2832 /// Both lhs and rhs unused.
2833 string_literal,
2829 /// main_token is the first token index (redundant with lhs)2834 /// main_token is the first token index (redundant with lhs)
2830 /// lhs is the first token index; rhs is the last token index.2835 /// lhs is the first token index; rhs is the last token index.
2831 /// Could be a series of multiline_string_literal_line tokens, or a single2836 /// Could be a series of multiline_string_literal_line tokens, or a single
2832 /// string_literal token.2837 /// string_literal token.
2833 string_literal,2838 multiline_string_literal,
2834 /// `(lhs)`. main_token is the `(`; rhs is the token index of the `)`.2839 /// `(lhs)`. main_token is the `(`; rhs is the token index of the `)`.
2835 grouped_expression,2840 grouped_expression,
2836 /// `@a(lhs, rhs)`. lhs and rhs may be omitted.2841 /// `@a(lhs, rhs)`. lhs and rhs may be omitted.
lib/std/zig/parse.zig+6-6
...@@ -2595,8 +2595,8 @@ const Parser = struct {...@@ -2595,8 +2595,8 @@ const Parser = struct {
2595 .tag = .string_literal,2595 .tag = .string_literal,
2596 .main_token = main_token,2596 .main_token = main_token,
2597 .data = .{2597 .data = .{
2598 .lhs = main_token,2598 .lhs = undefined,
2599 .rhs = main_token,2599 .rhs = undefined,
2600 },2600 },
2601 });2601 });
2602 },2602 },
...@@ -2633,7 +2633,7 @@ const Parser = struct {...@@ -2633,7 +2633,7 @@ const Parser = struct {
2633 p.tok_i += 1;2633 p.tok_i += 1;
2634 }2634 }
2635 return p.addNode(.{2635 return p.addNode(.{
2636 .tag = .string_literal,2636 .tag = .multiline_string_literal,
2637 .main_token = first_line,2637 .main_token = first_line,
2638 .data = .{2638 .data = .{
2639 .lhs = first_line,2639 .lhs = first_line,
...@@ -3996,8 +3996,8 @@ const Parser = struct {...@@ -3996,8 +3996,8 @@ const Parser = struct {
3996 .tag = .string_literal,3996 .tag = .string_literal,
3997 .main_token = main_token,3997 .main_token = main_token,
3998 .data = .{3998 .data = .{
3999 .lhs = main_token,3999 .lhs = undefined,
4000 .rhs = main_token,4000 .rhs = undefined,
4001 },4001 },
4002 });4002 });
4003 },4003 },
...@@ -4007,7 +4007,7 @@ const Parser = struct {...@@ -4007,7 +4007,7 @@ const Parser = struct {
4007 p.tok_i += 1;4007 p.tok_i += 1;
4008 }4008 }
4009 return p.addNode(.{4009 return p.addNode(.{
4010 .tag = .string_literal,4010 .tag = .multiline_string_literal,
4011 .main_token = first_line,4011 .main_token = first_line,
4012 .data = .{4012 .data = .{
4013 .lhs = first_line,4013 .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...@@ -153,29 +153,25 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
153 .unreachable_literal,153 .unreachable_literal,
154 .undefined_literal,154 .undefined_literal,
155 .anyframe_literal,155 .anyframe_literal,
156 .string_literal,
156 => return renderToken(ais, tree, main_tokens[node], space),157 => return renderToken(ais, tree, main_tokens[node], space),
157158
158 .string_literal => switch (token_tags[main_tokens[node]]) {159 .multiline_string_literal => {
159 .string_literal => try renderToken(ais, tree, main_tokens[node], space),160 var locked_indents = ais.lockOneShotIndent();
161 try ais.maybeInsertNewline();
160162
161 .multiline_string_literal_line => {163 var i = datas[node].lhs;
162 var locked_indents = ais.lockOneShotIndent();164 while (i <= datas[node].rhs) : (i += 1) try renderToken(ais, tree, i, .newline);
163 try ais.maybeInsertNewline();
164165
165 var i = datas[node].lhs;166 while (locked_indents > 0) : (locked_indents -= 1) ais.popIndent();
166 while (i <= datas[node].rhs) : (i += 1) try renderToken(ais, tree, i, .newline);
167167
168 while (locked_indents > 0) : (locked_indents -= 1) ais.popIndent();168 switch (space) {
169169 .none => {},
170 switch (space) {170 .semicolon => if (token_tags[i] == .semicolon) try renderToken(ais, tree, i, .newline),
171 .none => {},171 .comma => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .newline),
172 .semicolon => if (token_tags[i] == .semicolon) try renderToken(ais, tree, i, .newline),172 .comma_space => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .space),
173 .comma => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .newline),173 else => unreachable,
174 .comma_space => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .space),174 }
175 else => unreachable,
176 }
177 },
178 else => unreachable,
179 },175 },
180176
181 .error_value => {177 .error_value => {
...@@ -1850,8 +1846,7 @@ fn renderCall(...@@ -1850,8 +1846,7 @@ fn renderCall(
1850 try renderExpression(ais, tree, param_node, Space.none);1846 try renderExpression(ais, tree, param_node, Space.none);
18511847
1852 // Unindent the comma for multiline string literals1848 // Unindent the comma for multiline string literals
1853 const is_multiline_string = node_tags[param_node] == .string_literal and1849 const is_multiline_string = node_tags[param_node] == .multiline_string_literal;
1854 token_tags[main_tokens[param_node]] == .multiline_string_literal_line;
1855 if (is_multiline_string) ais.popIndent();1850 if (is_multiline_string) ais.popIndent();
18561851
1857 const comma = tree.lastToken(param_node) + 1;1852 const comma = tree.lastToken(param_node) + 1;
src/astgen.zig+247-163
...@@ -56,7 +56,8 @@ pub const ResultLoc = union(enum) {...@@ -56,7 +56,8 @@ pub const ResultLoc = union(enum) {
56};56};
5757
58pub fn typeExpr(mod: *Module, scope: *Scope, type_node: ast.Node.Index) InnerError!*zir.Inst {58pub 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)];
60 const type_type = try addZIRInstConst(mod, scope, type_src, .{61 const type_type = try addZIRInstConst(mod, scope, type_src, .{
61 .ty = Type.initTag(.type),62 .ty = Type.initTag(.type),
62 .val = Value.initTag(.type_type),63 .val = Value.initTag(.type_type),
...@@ -258,18 +259,23 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In...@@ -258,18 +259,23 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
258 .array_cat => return simpleBinOp(mod, scope, rl, node, .array_cat),259 .array_cat => return simpleBinOp(mod, scope, rl, node, .array_cat),
259 .array_mult => return simpleBinOp(mod, scope, rl, node, .array_mul),260 .array_mult => return simpleBinOp(mod, scope, rl, node, .array_mul),
260261
261 .bool_and => return boolBinOp(mod, scope, rl, node),262 .bool_and => return boolBinOp(mod, scope, rl, node, true),
262 .bool_or => return boolBinOp(mod, scope, rl, node),263 .bool_or => return boolBinOp(mod, scope, rl, node, false),
263264
264 .bool_not => return rvalue(mod, scope, rl, try boolNot(mod, scope, node)),265 .bool_not => return rvalue(mod, scope, rl, try boolNot(mod, scope, node)),
265 .bit_not => return rvalue(mod, scope, rl, try bitNot(mod, scope, node)),266 .bit_not => return rvalue(mod, scope, rl, try bitNot(mod, scope, node)),
266 .negation => return rvalue(mod, scope, rl, try negation(mod, scope, node, .sub)),267 .negation => return rvalue(mod, scope, rl, try negation(mod, scope, node, .sub)),
267 .negation_wrap => return rvalue(mod, scope, rl, try negation(mod, scope, node, .subwrap)),268 .negation_wrap => return rvalue(mod, scope, rl, try negation(mod, scope, node, .subwrap)),
268269
269 .identifier => return try identifier(mod, scope, rl, node),270 .identifier => return identifier(mod, scope, rl, node),
270 .@"asm" => return rvalue(mod, scope, rl, try assembly(mod, scope, node)),271
271 .string_literal => return rvalue(mod, scope, rl, try stringLiteral(mod, scope, node)),272 .asm_simple => return assembly(mod, scope, rl, tree.asmSimple(node)),
272 .integer_literal => return rvalue(mod, scope, rl, try integerLiteral(mod, scope, 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),
273 .builtin_call => return builtinCall(mod, scope, rl, node),279 .builtin_call => return builtinCall(mod, scope, rl, node),
274 .call => return callExpr(mod, scope, rl, node),280 .call => return callExpr(mod, scope, rl, node),
275 .@"unreachable" => return unreach(mod, scope, node),281 .@"unreachable" => return unreach(mod, scope, node),
...@@ -285,7 +291,22 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In...@@ -285,7 +291,22 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
285 .null_literal => return rvalue(mod, scope, rl, try nullLiteral(mod, scope, node)),291 .null_literal => return rvalue(mod, scope, rl, try nullLiteral(mod, scope, node)),
286 .optional_type => return rvalue(mod, scope, rl, try optionalType(mod, scope, node)),292 .optional_type => return rvalue(mod, scope, rl, try optionalType(mod, scope, node)),
287 .unwrap_optional => return unwrapOptional(mod, scope, rl, node),293 .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
289 .labeled_block => return labeledBlockExpr(mod, scope, rl, node, .block),310 .labeled_block => return labeledBlockExpr(mod, scope, rl, node, .block),
290 .@"break" => return rvalue(mod, scope, rl, try breakExpr(mod, scope, node)),311 .@"break" => return rvalue(mod, scope, rl, try breakExpr(mod, scope, node)),
291 .@"continue" => return rvalue(mod, scope, rl, try continueExpr(mod, scope, node)),312 .@"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...@@ -293,7 +314,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
293 .array_type => return rvalue(mod, scope, rl, try arrayType(mod, scope, node)),314 .array_type => return rvalue(mod, scope, rl, try arrayType(mod, scope, node)),
294 .array_type_sentinel => return rvalue(mod, scope, rl, try arrayTypeSentinel(mod, scope, node)),315 .array_type_sentinel => return rvalue(mod, scope, rl, try arrayTypeSentinel(mod, scope, node)),
295 .enum_literal => return rvalue(mod, scope, rl, try enumLiteral(mod, scope, node)),316 .enum_literal => return rvalue(mod, scope, rl, try enumLiteral(mod, scope, node)),
296 .MultilineStringLiteral => return rvalue(mod, scope, rl, try multilineStrLiteral(mod, scope, node)),
297 .char_literal => return rvalue(mod, scope, rl, try charLiteral(mod, scope, node)),317 .char_literal => return rvalue(mod, scope, rl, try charLiteral(mod, scope, node)),
298 .slice_type => return rvalue(mod, scope, rl, try sliceType(mod, scope, node)),318 .slice_type => return rvalue(mod, scope, rl, try sliceType(mod, scope, node)),
299 .error_union => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node, .error_union_type)),319 .error_union => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node, .error_union_type)),
...@@ -343,10 +363,17 @@ pub fn comptimeExpr(...@@ -343,10 +363,17 @@ pub fn comptimeExpr(
343 return expr(mod, parent_scope, rl, node);363 return expr(mod, parent_scope, rl, node);
344 }364 }
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
346 // Optimization for labeled blocks: don't need to have 2 layers of blocks,370 // Optimization for labeled blocks: don't need to have 2 layers of blocks,
347 // we can reuse the existing one.371 // we can reuse the existing one.
348 if (node.castTag(.labeled_block)) |block_node| {372 const lbrace = main_tokens[node];
349 return labeledBlockExpr(mod, parent_scope, rl, block_node, .block_comptime);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);
350 }377 }
351378
352 // Make a scope to collect generated instructions in the sub-expression.379 // Make a scope to collect generated instructions in the sub-expression.
...@@ -363,11 +390,7 @@ pub fn comptimeExpr(...@@ -363,11 +390,7 @@ pub fn comptimeExpr(
363 // instruction is the block's result value.390 // instruction is the block's result value.
364 _ = try expr(mod, &block_scope.base, rl, node);391 _ = try expr(mod, &block_scope.base, rl, node);
365392
366 const tree = parent_scope.tree();393 const src = token_starts[tree.firstToken(node)];
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
371 const block = try addZIRInstBlock(mod, parent_scope, src, .block_comptime_flat, .{394 const block = try addZIRInstBlock(mod, parent_scope, src, .block_comptime_flat, .{
372 .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items),395 .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items),
373 });396 });
...@@ -375,15 +398,13 @@ pub fn comptimeExpr(...@@ -375,15 +398,13 @@ pub fn comptimeExpr(
375 return &block.base;398 return &block.base;
376}399}
377400
378fn breakExpr(401fn breakExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst {
379 mod: *Module,
380 parent_scope: *Scope,
381 node: *ast.Node.ControlFlowExpression,
382) InnerError!*zir.Inst {
383 const tree = parent_scope.tree();402 const tree = parent_scope.tree();
384 const node_datas = tree.nodes.items(.data);403 const node_datas = tree.nodes.items(.data);
385 const main_tokens = tree.nodes.items(.main_token);404 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
388 // Look for the label in the scope.409 // Look for the label in the scope.
389 var scope = parent_scope;410 var scope = parent_scope;
...@@ -393,7 +414,7 @@ fn breakExpr(...@@ -393,7 +414,7 @@ fn breakExpr(
393 const gen_zir = scope.cast(Scope.GenZIR).?;414 const gen_zir = scope.cast(Scope.GenZIR).?;
394415
395 const block_inst = blk: {416 const block_inst = blk: {
396 if (node.getLabel()) |break_label| {417 if (break_label != 0) {
397 if (gen_zir.label) |*label| {418 if (gen_zir.label) |*label| {
398 if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) {419 if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) {
399 label.used = true;420 label.used = true;
...@@ -407,11 +428,11 @@ fn breakExpr(...@@ -407,11 +428,11 @@ fn breakExpr(
407 continue;428 continue;
408 };429 };
409430
410 const rhs = node.getRHS() orelse {431 if (rhs == 0) {
411 return addZirInstTag(mod, parent_scope, src, .break_void, .{432 return addZirInstTag(mod, parent_scope, src, .break_void, .{
412 .block = block_inst,433 .block = block_inst,
413 });434 });
414 };435 }
415 gen_zir.break_count += 1;436 gen_zir.break_count += 1;
416 const prev_rvalue_rl_count = gen_zir.rvalue_rl_count;437 const prev_rvalue_rl_count = gen_zir.rvalue_rl_count;
417 const operand = try expr(mod, parent_scope, gen_zir.break_result_loc, rhs);438 const operand = try expr(mod, parent_scope, gen_zir.break_result_loc, rhs);
...@@ -435,7 +456,7 @@ fn breakExpr(...@@ -435,7 +456,7 @@ fn breakExpr(
435 },456 },
436 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,457 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,
437 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,458 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,
438 else => if (node.getLabel()) |break_label| {459 else => if (break_label != 0) {
439 const label_name = try mod.identifierTokenString(parent_scope, break_label);460 const label_name = try mod.identifierTokenString(parent_scope, break_label);
440 return mod.failTok(parent_scope, break_label, "label not found: '{s}'", .{label_name});461 return mod.failTok(parent_scope, break_label, "label not found: '{s}'", .{label_name});
441 } else {462 } else {
...@@ -445,11 +466,12 @@ fn breakExpr(...@@ -445,11 +466,12 @@ fn breakExpr(
445 }466 }
446}467}
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 {
449 const tree = parent_scope.tree();470 const tree = parent_scope.tree();
450 const node_datas = tree.nodes.items(.data);471 const node_datas = tree.nodes.items(.data);
451 const main_tokens = tree.nodes.items(.main_token);472 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
454 // Look for the label in the scope.476 // Look for the label in the scope.
455 var scope = parent_scope;477 var scope = parent_scope;
...@@ -461,7 +483,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE...@@ -461,7 +483,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE
461 scope = gen_zir.parent;483 scope = gen_zir.parent;
462 continue;484 continue;
463 };485 };
464 if (node.getLabel()) |break_label| blk: {486 if (break_label != 0) blk: {
465 if (gen_zir.label) |*label| {487 if (gen_zir.label) |*label| {
466 if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) {488 if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) {
467 label.used = true;489 label.used = true;
...@@ -479,7 +501,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE...@@ -479,7 +501,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE
479 },501 },
480 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,502 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,
481 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,503 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,
482 else => if (node.getLabel()) |break_label| {504 else => if (break_label != 0) {
483 const label_name = try mod.identifierTokenString(parent_scope, break_label);505 const label_name = try mod.identifierTokenString(parent_scope, break_label);
484 return mod.failTok(parent_scope, break_label, "label not found: '{s}'", .{label_name});506 return mod.failTok(parent_scope, break_label, "label not found: '{s}'", .{label_name});
485 } else {507 } else {
...@@ -489,11 +511,18 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE...@@ -489,11 +511,18 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE
489 }511 }
490}512}
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 {
493 const tracy = trace(@src());521 const tracy = trace(@src());
494 defer tracy.end();522 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, {});
497}526}
498527
499fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIndex) !void {528fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIndex) !void {
...@@ -508,8 +537,8 @@ fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIn...@@ -508,8 +537,8 @@ fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIn
508 const tree = parent_scope.tree();537 const tree = parent_scope.tree();
509 const node_datas = tree.nodes.items(.data);538 const node_datas = tree.nodes.items(.data);
510 const main_tokens = tree.nodes.items(.main_token);539 const main_tokens = tree.nodes.items(.main_token);
511 const label_src = tree.token_locs[label].start;540 const label_src = token_starts[label];
512 const prev_label_src = tree.token_locs[prev_label.token].start;541 const prev_label_src = token_starts[prev_label.token];
513542
514 const label_name = try mod.identifierTokenString(parent_scope, label);543 const label_name = try mod.identifierTokenString(parent_scope, label);
515 const msg = msg: {544 const msg = msg: {
...@@ -556,7 +585,7 @@ fn labeledBlockExpr(...@@ -556,7 +585,7 @@ fn labeledBlockExpr(
556 const tree = parent_scope.tree();585 const tree = parent_scope.tree();
557 const node_datas = tree.nodes.items(.data);586 const node_datas = tree.nodes.items(.data);
558 const main_tokens = tree.nodes.items(.main_token);587 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
561 try checkLabelRedefinition(mod, parent_scope, block_node.label);590 try checkLabelRedefinition(mod, parent_scope, block_node.label);
562591
...@@ -595,7 +624,7 @@ fn labeledBlockExpr(...@@ -595,7 +624,7 @@ fn labeledBlockExpr(
595 try blockExprStmts(mod, &block_scope.base, &block_node.base, block_node.statements());624 try blockExprStmts(mod, &block_scope.base, &block_node.base, block_node.statements());
596625
597 if (!block_scope.label.?.used) {626 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", .{});
599 }628 }
600629
601 try gen_zir.instructions.append(mod.gpa, &block_inst.base);630 try gen_zir.instructions.append(mod.gpa, &block_inst.base);
...@@ -647,7 +676,7 @@ fn blockExprStmts(...@@ -647,7 +676,7 @@ fn blockExprStmts(
647676
648 var scope = parent_scope;677 var scope = parent_scope;
649 for (statements) |statement| {678 for (statements) |statement| {
650 const src = tree.token_locs[statement.firstToken()].start;679 const src = token_starts[statement.firstToken()];
651 _ = try addZIRNoOp(mod, scope, src, .dbg_stmt);680 _ = try addZIRNoOp(mod, scope, src, .dbg_stmt);
652 switch (statement.tag) {681 switch (statement.tag) {
653 .var_decl => {682 .var_decl => {
...@@ -694,7 +723,7 @@ fn varDecl(...@@ -694,7 +723,7 @@ fn varDecl(
694 const tree = scope.tree();723 const tree = scope.tree();
695 const node_datas = tree.nodes.items(.data);724 const node_datas = tree.nodes.items(.data);
696 const main_tokens = tree.nodes.items(.main_token);725 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];
698 const ident_name = try mod.identifierTokenString(scope, node.name_token);727 const ident_name = try mod.identifierTokenString(scope, node.name_token);
699728
700 // Local variables shadowing detection, including function parameters.729 // Local variables shadowing detection, including function parameters.
...@@ -911,34 +940,46 @@ fn assignOp(...@@ -911,34 +940,46 @@ fn assignOp(
911 _ = try addZIRBinOp(mod, scope, src, .store, lhs_ptr, result);940 _ = try addZIRBinOp(mod, scope, src, .store, lhs_ptr, result);
912}941}
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 {
915 const tree = scope.tree();944 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]];
917 const bool_type = try addZIRInstConst(mod, scope, src, .{949 const bool_type = try addZIRInstConst(mod, scope, src, .{
918 .ty = Type.initTag(.type),950 .ty = Type.initTag(.type),
919 .val = Value.initTag(.bool_type),951 .val = Value.initTag(.bool_type),
920 });952 });
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);
922 return addZIRUnOp(mod, scope, src, .bool_not, operand);954 return addZIRUnOp(mod, scope, src, .bool_not, operand);
923}955}
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 {
926 const tree = scope.tree();958 const tree = scope.tree();
927 const src = tree.token_locs[node.op_token].start;959 const node_datas = tree.nodes.items(.data);
928 const operand = try expr(mod, scope, .none, node.rhs);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);
929 return addZIRUnOp(mod, scope, src, .bit_not, operand);964 return addZIRUnOp(mod, scope, src, .bit_not, operand);
930}965}
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 {
933 const tree = scope.tree();973 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]];
936 const lhs = try addZIRInstConst(mod, scope, src, .{978 const lhs = try addZIRInstConst(mod, scope, src, .{
937 .ty = Type.initTag(.comptime_int),979 .ty = Type.initTag(.comptime_int),
938 .val = Value.initTag(.zero),980 .val = Value.initTag(.zero),
939 });981 });
940 const rhs = try expr(mod, scope, .none, node.rhs);982 const rhs = try expr(mod, scope, .none, node_datas[node].lhs);
941
942 return addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs);983 return addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs);
943}984}
944985
...@@ -948,20 +989,20 @@ fn addressOf(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerE...@@ -948,20 +989,20 @@ fn addressOf(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerE
948989
949fn optionalType(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst {990fn optionalType(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst {
950 const tree = scope.tree();991 const tree = scope.tree();
951 const src = tree.token_locs[node.op_token].start;992 const src = token_starts[node.op_token];
952 const operand = try typeExpr(mod, scope, node.rhs);993 const operand = try typeExpr(mod, scope, node.rhs);
953 return addZIRUnOp(mod, scope, src, .optional_type, operand);994 return addZIRUnOp(mod, scope, src, .optional_type, operand);
954}995}
955996
956fn sliceType(mod: *Module, scope: *Scope, node: *ast.Node.slice_type) InnerError!*zir.Inst {997fn sliceType(mod: *Module, scope: *Scope, node: *ast.Node.slice_type) InnerError!*zir.Inst {
957 const tree = scope.tree();998 const tree = scope.tree();
958 const src = tree.token_locs[node.op_token].start;999 const src = token_starts[node.op_token];
959 return ptrSliceType(mod, scope, src, &node.ptr_info, node.rhs, .Slice);1000 return ptrSliceType(mod, scope, src, &node.ptr_info, node.rhs, .Slice);
960}1001}
9611002
962fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir.Inst {1003fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir.Inst {
963 const tree = scope.tree();1004 const tree = scope.tree();
964 const src = tree.token_locs[node.op_token].start;1005 const src = token_starts[node.op_token];
965 return ptrSliceType(mod, scope, src, &node.ptr_info, node.rhs, switch (tree.token_ids[node.op_token]) {1006 return ptrSliceType(mod, scope, src, &node.ptr_info, node.rhs, switch (tree.token_ids[node.op_token]) {
966 .Asterisk, .AsteriskAsterisk => .One,1007 .Asterisk, .AsteriskAsterisk => .One,
967 // TODO stage1 type inference bug1008 // TODO stage1 type inference bug
...@@ -1018,7 +1059,7 @@ fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo,...@@ -1018,7 +1059,7 @@ fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo,
10181059
1019fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.array_type) !*zir.Inst {1060fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.array_type) !*zir.Inst {
1020 const tree = scope.tree();1061 const tree = scope.tree();
1021 const src = tree.token_locs[node.op_token].start;1062 const src = token_starts[node.op_token];
1022 const usize_type = try addZIRInstConst(mod, scope, src, .{1063 const usize_type = try addZIRInstConst(mod, scope, src, .{
1023 .ty = Type.initTag(.type),1064 .ty = Type.initTag(.type),
1024 .val = Value.initTag(.usize_type),1065 .val = Value.initTag(.usize_type),
...@@ -1033,7 +1074,7 @@ fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.array_type) !*zir.Inst...@@ -1033,7 +1074,7 @@ fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.array_type) !*zir.Inst
10331074
1034fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.array_type_sentinel) !*zir.Inst {1075fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.array_type_sentinel) !*zir.Inst {
1035 const tree = scope.tree();1076 const tree = scope.tree();
1036 const src = tree.token_locs[node.op_token].start;1077 const src = token_starts[node.op_token];
1037 const usize_type = try addZIRInstConst(mod, scope, src, .{1078 const usize_type = try addZIRInstConst(mod, scope, src, .{
1038 .ty = Type.initTag(.type),1079 .ty = Type.initTag(.type),
1039 .val = Value.initTag(.usize_type),1080 .val = Value.initTag(.usize_type),
...@@ -1054,7 +1095,7 @@ fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.array_type_sen...@@ -1054,7 +1095,7 @@ fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.array_type_sen
10541095
1055fn anyFrameType(mod: *Module, scope: *Scope, node: *ast.Node.anyframe_type) InnerError!*zir.Inst {1096fn anyFrameType(mod: *Module, scope: *Scope, node: *ast.Node.anyframe_type) InnerError!*zir.Inst {
1056 const tree = scope.tree();1097 const tree = scope.tree();
1057 const src = tree.token_locs[node.anyframe_token].start;1098 const src = token_starts[node.anyframe_token];
1058 if (node.result) |some| {1099 if (node.result) |some| {
1059 const return_type = try typeExpr(mod, scope, some.return_type);1100 const return_type = try typeExpr(mod, scope, some.return_type);
1060 return addZIRUnOp(mod, scope, src, .anyframe_type, return_type);1101 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...@@ -1068,7 +1109,7 @@ fn anyFrameType(mod: *Module, scope: *Scope, node: *ast.Node.anyframe_type) Inne
10681109
1069fn typeInixOp(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp, op_inst_tag: zir.Inst.Tag) InnerError!*zir.Inst {1110fn typeInixOp(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp, op_inst_tag: zir.Inst.Tag) InnerError!*zir.Inst {
1070 const tree = scope.tree();1111 const tree = scope.tree();
1071 const src = tree.token_locs[node.op_token].start;1112 const src = token_starts[node.op_token];
1072 const error_set = try typeExpr(mod, scope, node.lhs);1113 const error_set = try typeExpr(mod, scope, node.lhs);
1073 const payload = try typeExpr(mod, scope, node.rhs);1114 const payload = try typeExpr(mod, scope, node.rhs);
1074 return addZIRBinOp(mod, scope, src, op_inst_tag, error_set, payload);1115 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...@@ -1076,7 +1117,7 @@ fn typeInixOp(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp, op_ins
10761117
1077fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.enum_literal) !*zir.Inst {1118fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.enum_literal) !*zir.Inst {
1078 const tree = scope.tree();1119 const tree = scope.tree();
1079 const src = tree.token_locs[node.name].start;1120 const src = token_starts[node.name];
1080 const name = try mod.identifierTokenString(scope, node.name);1121 const name = try mod.identifierTokenString(scope, node.name);
10811122
1082 return addZIRInst(mod, scope, src, zir.Inst.EnumLiteral, .{ .name = name }, .{});1123 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....@@ -1084,7 +1125,7 @@ fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.enum_literal) !*zir.
10841125
1085fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {1126fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {
1086 const tree = scope.tree();1127 const tree = scope.tree();
1087 const src = tree.token_locs[node.rtoken].start;1128 const src = token_starts[node.rtoken];
10881129
1089 const operand = try expr(mod, scope, rl, node.lhs);1130 const operand = try expr(mod, scope, rl, node.lhs);
1090 const op: zir.Inst.Tag = switch (rl) {1131 const op: zir.Inst.Tag = switch (rl) {
...@@ -1100,7 +1141,7 @@ fn containerField(...@@ -1100,7 +1141,7 @@ fn containerField(
1100 node: *ast.Node.ContainerField,1141 node: *ast.Node.ContainerField,
1101) InnerError!*zir.Inst {1142) InnerError!*zir.Inst {
1102 const tree = scope.tree();1143 const tree = scope.tree();
1103 const src = tree.token_locs[node.firstToken()].start;1144 const src = token_starts[tree.firstToken(node)];
1104 const name = try mod.identifierTokenString(scope, node.name_token);1145 const name = try mod.identifierTokenString(scope, node.name_token);
11051146
1106 if (node.comptime_token == null and node.value_expr == null and node.align_expr == null) {1147 if (node.comptime_token == null and node.value_expr == null and node.align_expr == null) {
...@@ -1133,7 +1174,7 @@ fn containerField(...@@ -1133,7 +1174,7 @@ fn containerField(
11331174
1134fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.ContainerDecl) InnerError!*zir.Inst {1175fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.ContainerDecl) InnerError!*zir.Inst {
1135 const tree = scope.tree();1176 const tree = scope.tree();
1136 const src = tree.token_locs[node.kind_token].start;1177 const src = token_starts[node.kind_token];
11371178
1138 var gen_scope: Scope.GenZIR = .{1179 var gen_scope: Scope.GenZIR = .{
1139 .parent = scope,1180 .parent = scope,
...@@ -1278,7 +1319,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con...@@ -1278,7 +1319,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
12781319
1279fn errorSetDecl(mod: *Module, scope: *Scope, node: *ast.Node.error_set_decl) InnerError!*zir.Inst {1320fn errorSetDecl(mod: *Module, scope: *Scope, node: *ast.Node.error_set_decl) InnerError!*zir.Inst {
1280 const tree = scope.tree();1321 const tree = scope.tree();
1281 const src = tree.token_locs[node.error_token].start;1322 const src = token_starts[node.error_token];
1282 const decls = node.decls();1323 const decls = node.decls();
1283 const fields = try scope.arena().alloc([]const u8, decls.len);1324 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...@@ -1292,7 +1333,7 @@ fn errorSetDecl(mod: *Module, scope: *Scope, node: *ast.Node.error_set_decl) Inn
12921333
1293fn errorType(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst {1334fn errorType(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst {
1294 const tree = scope.tree();1335 const tree = scope.tree();
1295 const src = tree.token_locs[node.token].start;1336 const src = token_starts[node.token];
1296 return addZIRInstConst(mod, scope, src, .{1337 return addZIRInstConst(mod, scope, src, .{
1297 .ty = Type.initTag(.type),1338 .ty = Type.initTag(.type),
1298 .val = Value.initTag(.anyerror_type),1339 .val = Value.initTag(.anyerror_type),
...@@ -1370,7 +1411,7 @@ fn orelseCatchExpr(...@@ -1370,7 +1411,7 @@ fn orelseCatchExpr(
1370 payload_node: ?*ast.Node,1411 payload_node: ?*ast.Node,
1371) InnerError!*zir.Inst {1412) InnerError!*zir.Inst {
1372 const tree = scope.tree();1413 const tree = scope.tree();
1373 const src = tree.token_locs[op_token].start;1414 const src = token_starts[op_token];
13741415
1375 var block_scope: Scope.GenZIR = .{1416 var block_scope: Scope.GenZIR = .{
1376 .parent = scope,1417 .parent = scope,
...@@ -1544,7 +1585,7 @@ fn tokenIdentEql(mod: *Module, scope: *Scope, token1: ast.TokenIndex, token2: as...@@ -1544,7 +1585,7 @@ fn tokenIdentEql(mod: *Module, scope: *Scope, token1: ast.TokenIndex, token2: as
15441585
1545pub fn field(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleInfixOp) InnerError!*zir.Inst {1586pub fn field(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleInfixOp) InnerError!*zir.Inst {
1546 const tree = scope.tree();1587 const tree = scope.tree();
1547 const src = tree.token_locs[node.op_token].start;1588 const src = token_starts[node.op_token];
1548 // TODO custom AST node for field access so that we don't have to go through a node cast here1589 // TODO custom AST node for field access so that we don't have to go through a node cast here
1549 const field_name = try mod.identifierTokenString(scope, node.rhs.castTag(.identifier).?.token);1590 const field_name = try mod.identifierTokenString(scope, node.rhs.castTag(.identifier).?.token);
1550 if (rl == .ref) {1591 if (rl == .ref) {
...@@ -1568,7 +1609,7 @@ fn namedField(...@@ -1568,7 +1609,7 @@ fn namedField(
1568 try ensureBuiltinParamCount(mod, scope, call, 2);1609 try ensureBuiltinParamCount(mod, scope, call, 2);
15691610
1570 const tree = scope.tree();1611 const tree = scope.tree();
1571 const src = tree.token_locs[call.builtin_token].start;1612 const src = token_starts[call.builtin_token];
1572 const params = call.params();1613 const params = call.params();
15731614
1574 const string_type = try addZIRInstConst(mod, scope, src, .{1615 const string_type = try addZIRInstConst(mod, scope, src, .{
...@@ -1591,7 +1632,7 @@ fn namedField(...@@ -1591,7 +1632,7 @@ fn namedField(
15911632
1592fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.array_access) InnerError!*zir.Inst {1633fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.array_access) InnerError!*zir.Inst {
1593 const tree = scope.tree();1634 const tree = scope.tree();
1594 const src = tree.token_locs[node.rtoken].start;1635 const src = token_starts[node.rtoken];
1595 const usize_type = try addZIRInstConst(mod, scope, src, .{1636 const usize_type = try addZIRInstConst(mod, scope, src, .{
1596 .ty = Type.initTag(.type),1637 .ty = Type.initTag(.type),
1597 .val = Value.initTag(.usize_type),1638 .val = Value.initTag(.usize_type),
...@@ -1612,7 +1653,7 @@ fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.array...@@ -1612,7 +1653,7 @@ fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.array
16121653
1613fn sliceExpr(mod: *Module, scope: *Scope, node: *ast.Node.slice) InnerError!*zir.Inst {1654fn sliceExpr(mod: *Module, scope: *Scope, node: *ast.Node.slice) InnerError!*zir.Inst {
1614 const tree = scope.tree();1655 const tree = scope.tree();
1615 const src = tree.token_locs[node.rtoken].start;1656 const src = token_starts[node.rtoken];
16161657
1617 const usize_type = try addZIRInstConst(mod, scope, src, .{1658 const usize_type = try addZIRInstConst(mod, scope, src, .{
1618 .ty = Type.initTag(.type),1659 .ty = Type.initTag(.type),
...@@ -1642,7 +1683,7 @@ fn sliceExpr(mod: *Module, scope: *Scope, node: *ast.Node.slice) InnerError!*zir...@@ -1642,7 +1683,7 @@ fn sliceExpr(mod: *Module, scope: *Scope, node: *ast.Node.slice) InnerError!*zir
16421683
1643fn deref(mod: *Module, scope: *Scope, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {1684fn deref(mod: *Module, scope: *Scope, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {
1644 const tree = scope.tree();1685 const tree = scope.tree();
1645 const src = tree.token_locs[node.rtoken].start;1686 const src = token_starts[node.rtoken];
1646 const lhs = try expr(mod, scope, .none, node.lhs);1687 const lhs = try expr(mod, scope, .none, node.lhs);
1647 return addZIRUnOp(mod, scope, src, .deref, lhs);1688 return addZIRUnOp(mod, scope, src, .deref, lhs);
1648}1689}
...@@ -1669,13 +1710,14 @@ fn boolBinOp(...@@ -1669,13 +1710,14 @@ fn boolBinOp(
1669 mod: *Module,1710 mod: *Module,
1670 scope: *Scope,1711 scope: *Scope,
1671 rl: ResultLoc,1712 rl: ResultLoc,
1672 infix_node: *ast.Node.SimpleInfixOp,1713 infix_node: ast.Node.Index,
1714 is_bool_and: bool,
1673) InnerError!*zir.Inst {1715) InnerError!*zir.Inst {
1674 const tree = scope.tree();1716 const tree = scope.tree();
1675 const node_datas = tree.nodes.items(.data);1717 const node_datas = tree.nodes.items(.data);
1676 const main_tokens = tree.nodes.items(.main_token);1718 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]];
1679 const bool_type = try addZIRInstConst(mod, scope, src, .{1721 const bool_type = try addZIRInstConst(mod, scope, src, .{
1680 .ty = Type.initTag(.type),1722 .ty = Type.initTag(.type),
1681 .val = Value.initTag(.bool_type),1723 .val = Value.initTag(.bool_type),
...@@ -1690,7 +1732,7 @@ fn boolBinOp(...@@ -1690,7 +1732,7 @@ fn boolBinOp(
1690 };1732 };
1691 defer block_scope.instructions.deinit(mod.gpa);1733 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);
1694 const condbr = try addZIRInstSpecial(mod, &block_scope.base, src, zir.Inst.CondBr, .{1736 const condbr = try addZIRInstSpecial(mod, &block_scope.base, src, zir.Inst.CondBr, .{
1695 .condition = lhs,1737 .condition = lhs,
1696 .then_body = undefined, // populated below1738 .then_body = undefined, // populated below
...@@ -1710,7 +1752,7 @@ fn boolBinOp(...@@ -1710,7 +1752,7 @@ fn boolBinOp(
1710 };1752 };
1711 defer rhs_scope.instructions.deinit(mod.gpa);1753 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);
1714 _ = try addZIRInst(mod, &rhs_scope.base, src, zir.Inst.Break, .{1756 _ = try addZIRInst(mod, &rhs_scope.base, src, zir.Inst.Break, .{
1715 .block = block,1757 .block = block,
1716 .operand = rhs,1758 .operand = rhs,
...@@ -1725,7 +1767,6 @@ fn boolBinOp(...@@ -1725,7 +1767,6 @@ fn boolBinOp(
1725 };1767 };
1726 defer const_scope.instructions.deinit(mod.gpa);1768 defer const_scope.instructions.deinit(mod.gpa);
17271769
1728 const is_bool_and = infix_node.base.tag == .bool_and;
1729 _ = try addZIRInst(mod, &const_scope.base, src, zir.Inst.Break, .{1770 _ = try addZIRInst(mod, &const_scope.base, src, zir.Inst.Break, .{
1730 .block = block,1771 .block = block,
1731 .operand = try addZIRInstConst(mod, &const_scope.base, src, .{1772 .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")...@@ -1843,7 +1884,7 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.@"if")
1843 const tree = scope.tree();1884 const tree = scope.tree();
1844 const node_datas = tree.nodes.items(.data);1885 const node_datas = tree.nodes.items(.data);
1845 const main_tokens = tree.nodes.items(.main_token);1886 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];
1847 const cond = try cond_kind.cond(mod, &block_scope, if_src, if_node.condition);1888 const cond = try cond_kind.cond(mod, &block_scope, if_src, if_node.condition);
18481889
1849 const condbr = try addZIRInstSpecial(mod, &block_scope.base, if_src, zir.Inst.CondBr, .{1890 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")...@@ -1856,7 +1897,7 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.@"if")
1856 .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items),1897 .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items),
1857 });1898 });
18581899
1859 const then_src = tree.token_locs[if_node.body.lastToken()].start;1900 const then_src = token_starts[if_node.body.lastToken()];
1860 var then_scope: Scope.GenZIR = .{1901 var then_scope: Scope.GenZIR = .{
1861 .parent = scope,1902 .parent = scope,
1862 .decl = block_scope.decl,1903 .decl = block_scope.decl,
...@@ -1887,14 +1928,14 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.@"if")...@@ -1887,14 +1928,14 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.@"if")
1887 var else_src: usize = undefined;1928 var else_src: usize = undefined;
1888 var else_sub_scope: *Module.Scope = undefined;1929 var else_sub_scope: *Module.Scope = undefined;
1889 const else_result: ?*zir.Inst = if (if_node.@"else") |else_node| blk: {1930 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()];
1891 // declare payload to the then_scope1932 // declare payload to the then_scope
1892 else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload);1933 else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload);
18931934
1894 block_scope.break_count += 1;1935 block_scope.break_count += 1;
1895 break :blk try expr(mod, else_sub_scope, block_scope.break_result_loc, else_node.body);1936 break :blk try expr(mod, else_sub_scope, block_scope.break_result_loc, else_node.body);
1896 } else blk: {1937 } else blk: {
1897 else_src = tree.token_locs[if_node.lastToken()].start;1938 else_src = token_starts[if_node.lastToken()];
1898 else_sub_scope = &else_scope.base;1939 else_sub_scope = &else_scope.base;
1899 break :blk null;1940 break :blk null;
1900 };1941 };
...@@ -1981,7 +2022,7 @@ fn whileExpr(...@@ -1981,7 +2022,7 @@ fn whileExpr(
1981 const tree = scope.tree();2022 const tree = scope.tree();
1982 const node_datas = tree.nodes.items(.data);2023 const node_datas = tree.nodes.items(.data);
1983 const main_tokens = tree.nodes.items(.main_token);2024 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];
1985 const void_type = try addZIRInstConst(mod, scope, while_src, .{2026 const void_type = try addZIRInstConst(mod, scope, while_src, .{
1986 .ty = Type.initTag(.type),2027 .ty = Type.initTag(.type),
1987 .val = Value.initTag(.void_type),2028 .val = Value.initTag(.void_type),
...@@ -2028,7 +2069,7 @@ fn whileExpr(...@@ -2028,7 +2069,7 @@ fn whileExpr(
2028 });2069 });
2029 }2070 }
20302071
2031 const then_src = tree.token_locs[while_node.body.lastToken()].start;2072 const then_src = token_starts[while_node.body.lastToken()];
2032 var then_scope: Scope.GenZIR = .{2073 var then_scope: Scope.GenZIR = .{
2033 .parent = &continue_scope.base,2074 .parent = &continue_scope.base,
2034 .decl = continue_scope.decl,2075 .decl = continue_scope.decl,
...@@ -2055,19 +2096,19 @@ fn whileExpr(...@@ -2055,19 +2096,19 @@ fn whileExpr(
20552096
2056 var else_src: usize = undefined;2097 var else_src: usize = undefined;
2057 const else_result: ?*zir.Inst = if (while_node.@"else") |else_node| blk: {2098 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()];
2059 // declare payload to the then_scope2100 // declare payload to the then_scope
2060 const else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload);2101 const else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload);
20612102
2062 loop_scope.break_count += 1;2103 loop_scope.break_count += 1;
2063 break :blk try expr(mod, else_sub_scope, loop_scope.break_result_loc, else_node.body);2104 break :blk try expr(mod, else_sub_scope, loop_scope.break_result_loc, else_node.body);
2064 } else blk: {2105 } else blk: {
2065 else_src = tree.token_locs[while_node.lastToken()].start;2106 else_src = token_starts[while_node.lastToken()];
2066 break :blk null;2107 break :blk null;
2067 };2108 };
2068 if (loop_scope.label) |some| {2109 if (loop_scope.label) |some| {
2069 if (!some.used) {2110 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", .{});
2071 }2112 }
2072 }2113 }
2073 return finishThenElseBlock(2114 return finishThenElseBlock(
...@@ -2105,7 +2146,7 @@ fn forExpr(...@@ -2105,7 +2146,7 @@ fn forExpr(
2105 const tree = scope.tree();2146 const tree = scope.tree();
2106 const node_datas = tree.nodes.items(.data);2147 const node_datas = tree.nodes.items(.data);
2107 const main_tokens = tree.nodes.items(.main_token);2148 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];
2109 const index_ptr = blk: {2150 const index_ptr = blk: {
2110 const usize_type = try addZIRInstConst(mod, scope, for_src, .{2151 const usize_type = try addZIRInstConst(mod, scope, for_src, .{
2111 .ty = Type.initTag(.type),2152 .ty = Type.initTag(.type),
...@@ -2121,7 +2162,7 @@ fn forExpr(...@@ -2121,7 +2162,7 @@ fn forExpr(
2121 break :blk index_ptr;2162 break :blk index_ptr;
2122 };2163 };
2123 const array_ptr = try expr(mod, scope, .ref, for_node.array_expr);2164 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()];
2125 const len = try addZIRUnOp(mod, scope, cond_src, .indexable_ptr_len, array_ptr);2166 const len = try addZIRUnOp(mod, scope, cond_src, .indexable_ptr_len, array_ptr);
21262167
2127 var loop_scope: Scope.GenZIR = .{2168 var loop_scope: Scope.GenZIR = .{
...@@ -2191,7 +2232,7 @@ fn forExpr(...@@ -2191,7 +2232,7 @@ fn forExpr(
2191 }2232 }
21922233
2193 // while body2234 // while body
2194 const then_src = tree.token_locs[for_node.body.lastToken()].start;2235 const then_src = token_starts[for_node.body.lastToken()];
2195 var then_scope: Scope.GenZIR = .{2236 var then_scope: Scope.GenZIR = .{
2196 .parent = &cond_scope.base,2237 .parent = &cond_scope.base,
2197 .decl = cond_scope.decl,2238 .decl = cond_scope.decl,
...@@ -2215,7 +2256,7 @@ fn forExpr(...@@ -2215,7 +2256,7 @@ fn forExpr(
2215 const index_symbol_node = payload.index_symbol orelse2256 const index_symbol_node = payload.index_symbol orelse
2216 break :blk &then_scope.base;2257 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));
2219 if (mem.eql(u8, index_name, "_")) {2260 if (mem.eql(u8, index_name, "_")) {
2220 break :blk &then_scope.base;2261 break :blk &then_scope.base;
2221 }2262 }
...@@ -2244,16 +2285,16 @@ fn forExpr(...@@ -2244,16 +2285,16 @@ fn forExpr(
22442285
2245 var else_src: usize = undefined;2286 var else_src: usize = undefined;
2246 const else_result: ?*zir.Inst = if (for_node.@"else") |else_node| blk: {2287 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()];
2248 loop_scope.break_count += 1;2289 loop_scope.break_count += 1;
2249 break :blk try expr(mod, &else_scope.base, loop_scope.break_result_loc, else_node.body);2290 break :blk try expr(mod, &else_scope.base, loop_scope.break_result_loc, else_node.body);
2250 } else blk: {2291 } else blk: {
2251 else_src = tree.token_locs[for_node.lastToken()].start;2292 else_src = token_starts[for_node.lastToken()];
2252 break :blk null;2293 break :blk null;
2253 };2294 };
2254 if (loop_scope.label) |some| {2295 if (loop_scope.label) |some| {
2255 if (!some.used) {2296 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", .{});
2257 }2298 }
2258 }2299 }
2259 return finishThenElseBlock(2300 return finishThenElseBlock(
...@@ -2299,7 +2340,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node...@@ -2299,7 +2340,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node
2299 const tree = scope.tree();2340 const tree = scope.tree();
2300 const node_datas = tree.nodes.items(.data);2341 const node_datas = tree.nodes.items(.data);
2301 const main_tokens = tree.nodes.items(.main_token);2342 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];
2303 const use_ref = switchCaseUsesRef(switch_node);2344 const use_ref = switchCaseUsesRef(switch_node);
23042345
2305 var block_scope: Scope.GenZIR = .{2346 var block_scope: Scope.GenZIR = .{
...@@ -2322,7 +2363,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node...@@ -2322,7 +2363,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node
2322 var simple_case_count: usize = 0;2363 var simple_case_count: usize = 0;
2323 for (switch_node.cases()) |uncasted_case| {2364 for (switch_node.cases()) |uncasted_case| {
2324 const case = uncasted_case.castTag(.switch_case).?;2365 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()];
2326 assert(case.items_len != 0);2367 assert(case.items_len != 0);
23272368
2328 // Check for else/_ prong, those are handled last.2369 // Check for else/_ prong, those are handled last.
...@@ -2389,7 +2430,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node...@@ -2389,7 +2430,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node
2389 if (getRangeNode(item)) |range| {2430 if (getRangeNode(item)) |range| {
2390 const start = try comptimeExpr(mod, &block_scope.base, .none, range.lhs);2431 const start = try comptimeExpr(mod, &block_scope.base, .none, range.lhs);
2391 const end = try comptimeExpr(mod, &block_scope.base, .none, range.rhs);2432 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];
2393 const range_inst = try addZIRBinOp(mod, &block_scope.base, range_src, .switch_range, start, end);2434 const range_inst = try addZIRBinOp(mod, &block_scope.base, range_src, .switch_range, start, end);
2394 try items.append(range_inst);2435 try items.append(range_inst);
2395 } else {2436 } else {
...@@ -2447,7 +2488,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node...@@ -2447,7 +2488,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node
2447 var case_index: usize = 0;2488 var case_index: usize = 0;
2448 for (switch_node.cases()) |uncasted_case| {2489 for (switch_node.cases()) |uncasted_case| {
2449 const case = uncasted_case.castTag(.switch_case).?;2490 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()];
2451 // reset without freeing to reduce allocations.2492 // reset without freeing to reduce allocations.
2452 case_scope.instructions.items.len = 0;2493 case_scope.instructions.items.len = 0;
24532494
...@@ -2485,7 +2526,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node...@@ -2485,7 +2526,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node
2485 var any_ok: ?*zir.Inst = null;2526 var any_ok: ?*zir.Inst = null;
2486 for (case.items()) |item| {2527 for (case.items()) |item| {
2487 if (getRangeNode(item)) |range| {2528 if (getRangeNode(item)) |range| {
2488 const range_src = tree.token_locs[range.op_token].start;2529 const range_src = token_starts[range.op_token];
2489 const range_inst = items.items[items_index].castTag(.switch_range).?;2530 const range_inst = items.items[items_index].castTag(.switch_range).?;
2490 items_index += 1;2531 items_index += 1;
24912532
...@@ -2565,7 +2606,7 @@ fn switchCaseExpr(...@@ -2565,7 +2606,7 @@ fn switchCaseExpr(
2565 const tree = scope.tree();2606 const tree = scope.tree();
2566 const node_datas = tree.nodes.items(.data);2607 const node_datas = tree.nodes.items(.data);
2567 const main_tokens = tree.nodes.items(.main_token);2608 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()];
2569 const sub_scope = blk: {2610 const sub_scope = blk: {
2570 const uncasted_payload = case.payload orelse break :blk scope;2611 const uncasted_payload = case.payload orelse break :blk scope;
2571 const payload = uncasted_payload.castTag(.PointerPayload).?;2612 const payload = uncasted_payload.castTag(.PointerPayload).?;
...@@ -2593,7 +2634,7 @@ fn ret(mod: *Module, scope: *Scope, cfe: *ast.Node.ControlFlowExpression) InnerE...@@ -2593,7 +2634,7 @@ fn ret(mod: *Module, scope: *Scope, cfe: *ast.Node.ControlFlowExpression) InnerE
2593 const tree = scope.tree();2634 const tree = scope.tree();
2594 const node_datas = tree.nodes.items(.data);2635 const node_datas = tree.nodes.items(.data);
2595 const main_tokens = tree.nodes.items(.main_token);2636 const main_tokens = tree.nodes.items(.main_token);
2596 const src = tree.token_locs[cfe.ltoken].start;2637 const src = token_starts[cfe.ltoken];
2597 if (cfe.getRHS()) |rhs_node| {2638 if (cfe.getRHS()) |rhs_node| {
2598 if (nodeMayNeedMemoryLocation(rhs_node, scope)) {2639 if (nodeMayNeedMemoryLocation(rhs_node, scope)) {
2599 const ret_ptr = try addZIRNoOp(mod, scope, src, .ret_ptr);2640 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...@@ -2609,17 +2650,24 @@ fn ret(mod: *Module, scope: *Scope, cfe: *ast.Node.ControlFlowExpression) InnerE
2609 }2650 }
2610}2651}
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 {
2613 const tracy = trace(@src());2659 const tracy = trace(@src());
2614 defer tracy.end();2660 defer tracy.end();
26152661
2616 const tree = scope.tree();2662 const tree = scope.tree();
2617 const node_datas = tree.nodes.items(.data);2663 const node_datas = tree.nodes.items(.data);
2618 const main_tokens = tree.nodes.items(.main_token);2664 const main_tokens = tree.nodes.items(.main_token);
2619 const ident_name = try mod.identifierTokenString(scope, ident.token);2665
2620 const src = tree.token_locs[ident.token].start;2666 const ident_token = main_tokens[ident];
2667 const ident_name = try mod.identifierTokenString(scope, ident_token);
2668 const src = token_starts[ident_token];
2621 if (mem.eql(u8, ident_name, "_")) {2669 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", .{});
2623 }2671 }
26242672
2625 if (getSimplePrimitiveValue(ident_name)) |typed_value| {2673 if (getSimplePrimitiveValue(ident_name)) |typed_value| {
...@@ -2634,7 +2682,7 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo...@@ -2634,7 +2682,7 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo
2634 const bit_count = std.fmt.parseInt(u16, ident_name[1..], 10) catch |err| switch (err) {2682 const bit_count = std.fmt.parseInt(u16, ident_name[1..], 10) catch |err| switch (err) {
2635 error.Overflow => return mod.failNode(2683 error.Overflow => return mod.failNode(
2636 scope,2684 scope,
2637 &ident.base,2685 ident,
2638 "primitive integer type '{s}' exceeds maximum bit width of 65535",2686 "primitive integer type '{s}' exceeds maximum bit width of 65535",
2639 .{ident_name},2687 .{ident_name},
2640 ),2688 ),
...@@ -2698,64 +2746,91 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo...@@ -2698,64 +2746,91 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo
2698 }2746 }
2699 }2747 }
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});
2702}2750}
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 {
2705 const tree = scope.tree();2758 const tree = scope.tree();
2706 const node_datas = tree.nodes.items(.data);2759 const node_datas = tree.nodes.items(.data);
2707 const main_tokens = tree.nodes.items(.main_token);2760 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);
2709 const arena = scope.arena();2764 const arena = scope.arena();
27102765
2711 var bad_index: usize = undefined;2766 var bad_index: usize = undefined;
2712 const bytes = std.zig.parseStringLiteral(arena, unparsed_bytes, &bad_index) catch |err| switch (err) {2767 const bytes = std.zig.parseStringLiteral(arena, unparsed_bytes, &bad_index) catch |err| switch (err) {
2713 error.InvalidCharacter => {2768 error.InvalidCharacter => {
2714 const bad_byte = unparsed_bytes[bad_index];2769 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];
2716 return mod.fail(scope, src + bad_index, "invalid string literal character: '{c}'\n", .{bad_byte});2771 return mod.fail(scope, src + bad_index, "invalid string literal character: '{c}'\n", .{bad_byte});
2717 },2772 },
2718 else => |e| return e,2773 else => |e| return e,
2719 };2774 };
27202775
2721 const src = tree.token_locs[str_lit.token].start;2776 const src = token_starts[str_lit_token];
2722 return addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{});2777 const str_inst = try addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{});
2778 return rvalue(mod, scope, rl, str_inst);
2723}2779}
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 {
2726 const tree = scope.tree();2787 const tree = scope.tree();
2727 const node_datas = tree.nodes.items(.data);2788 const node_datas = tree.nodes.items(.data);
2728 const main_tokens = tree.nodes.items(.main_token);2789 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 lines2791 const start = node_datas[node].lhs;
2733 var len = lines.len - 1;2792 const end = node_datas[node].rhs;
2734 for (lines) |line| {
2735 // 2 for the '//' + 1 for '\n'
2736 len += tree.tokenSlice(line).len - 3;
2737 }
27382793
2739 const bytes = try scope.arena().alloc(u8, len);2794 // Count the number of bytes to allocate.
2740 var i: usize = 0;2795 const len: usize = len: {
2741 for (lines) |line, line_i| {2796 var tok_i = start;
2742 if (line_i != 0) {2797 var len: usize = 0;
2743 bytes[i] = '\n';2798 while (tok_i <= end) : (tok_i += 1) {
2744 i += 1;2799 // 2 for the '//' + 1 for '\n'
2800 len += tree.tokenSlice(tok_i).len - 3;
2745 }2801 }
2746 const slice = tree.tokenSlice(line);2802 break :len len;
2747 mem.copy(u8, bytes[i..], slice[2 .. slice.len - 1]);2803 };
2748 i += slice.len - 3;2804 const bytes = try scope.arena().alloc(u8, len);
2749 }2805 // First line: do not append a newline.
27502806 var byte_i: usize = 0;
2751 return addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{});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);
2752}2827}
27532828
2754fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst {2829fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst {
2755 const tree = scope.tree();2830 const tree = scope.tree();
2756 const node_datas = tree.nodes.items(.data);2831 const node_datas = tree.nodes.items(.data);
2757 const main_tokens = tree.nodes.items(.main_token);2832 const main_tokens = tree.nodes.items(.main_token);
2758 const src = tree.token_locs[node.token].start;2833 const src = token_starts[node.token];
2759 const slice = tree.tokenSlice(node.token);2834 const slice = tree.tokenSlice(node.token);
27602835
2761 var bad_index: usize = undefined;2836 var bad_index: usize = undefined;
...@@ -2772,13 +2847,19 @@ fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst...@@ -2772,13 +2847,19 @@ fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst
2772 });2847 });
2773}2848}
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 {
2776 const arena = scope.arena();2856 const arena = scope.arena();
2777 const tree = scope.tree();2857 const tree = scope.tree();
2778 const node_datas = tree.nodes.items(.data);
2779 const main_tokens = tree.nodes.items(.main_token);2858 const main_tokens = tree.nodes.items(.main_token);
2780 const prefixed_bytes = tree.tokenSlice(int_lit.token);2859
2781 const base = if (mem.startsWith(u8, prefixed_bytes, "0x"))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"))
2782 162863 16
2783 else if (mem.startsWith(u8, prefixed_bytes, "0o"))2864 else if (mem.startsWith(u8, prefixed_bytes, "0o"))
2784 82865 8
...@@ -2793,13 +2874,14 @@ fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) Inne...@@ -2793,13 +2874,14 @@ fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) Inne
2793 prefixed_bytes[2..];2874 prefixed_bytes[2..];
27942875
2795 if (std.fmt.parseInt(u64, bytes, base)) |small_int| {2876 if (std.fmt.parseInt(u64, bytes, base)) |small_int| {
2796 const src = tree.token_locs[int_lit.token].start;2877 const src = token_starts[int_token];
2797 return addZIRInstConst(mod, scope, src, .{2878 const result = try addZIRInstConst(mod, scope, src, .{
2798 .ty = Type.initTag(.comptime_int),2879 .ty = Type.initTag(.comptime_int),
2799 .val = try Value.Tag.int_u64.create(arena, small_int),2880 .val = try Value.Tag.int_u64.create(arena, small_int),
2800 });2881 });
2882 return rvalue(mod, scope, rl, result);
2801 } else |err| {2883 } 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", .{});
2803 }2885 }
2804}2886}
28052887
...@@ -2816,7 +2898,7 @@ fn floatLiteral(mod: *Module, scope: *Scope, float_lit: *ast.Node.OneToken) Inne...@@ -2816,7 +2898,7 @@ fn floatLiteral(mod: *Module, scope: *Scope, float_lit: *ast.Node.OneToken) Inne
2816 const float_number = std.fmt.parseFloat(f128, bytes) catch |e| switch (e) {2898 const float_number = std.fmt.parseFloat(f128, bytes) catch |e| switch (e) {
2817 error.InvalidCharacter => unreachable, // validated by tokenizer2899 error.InvalidCharacter => unreachable, // validated by tokenizer
2818 };2900 };
2819 const src = tree.token_locs[float_lit.token].start;2901 const src = token_starts[float_lit.token];
2820 return addZIRInstConst(mod, scope, src, .{2902 return addZIRInstConst(mod, scope, src, .{
2821 .ty = Type.initTag(.comptime_float),2903 .ty = Type.initTag(.comptime_float),
2822 .val = try Value.Tag.float_128.create(arena, float_number),2904 .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...@@ -2828,7 +2910,7 @@ fn undefLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerErro
2828 const tree = scope.tree();2910 const tree = scope.tree();
2829 const node_datas = tree.nodes.items(.data);2911 const node_datas = tree.nodes.items(.data);
2830 const main_tokens = tree.nodes.items(.main_token);2912 const main_tokens = tree.nodes.items(.main_token);
2831 const src = tree.token_locs[node.token].start;2913 const src = token_starts[node.token];
2832 return addZIRInstConst(mod, scope, src, .{2914 return addZIRInstConst(mod, scope, src, .{
2833 .ty = Type.initTag(.@"undefined"),2915 .ty = Type.initTag(.@"undefined"),
2834 .val = Value.initTag(.undef),2916 .val = Value.initTag(.undef),
...@@ -2840,7 +2922,7 @@ fn boolLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError...@@ -2840,7 +2922,7 @@ fn boolLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError
2840 const tree = scope.tree();2922 const tree = scope.tree();
2841 const node_datas = tree.nodes.items(.data);2923 const node_datas = tree.nodes.items(.data);
2842 const main_tokens = tree.nodes.items(.main_token);2924 const main_tokens = tree.nodes.items(.main_token);
2843 const src = tree.token_locs[node.token].start;2925 const src = token_starts[node.token];
2844 return addZIRInstConst(mod, scope, src, .{2926 return addZIRInstConst(mod, scope, src, .{
2845 .ty = Type.initTag(.bool),2927 .ty = Type.initTag(.bool),
2846 .val = switch (tree.token_ids[node.token]) {2928 .val = switch (tree.token_ids[node.token]) {
...@@ -2856,34 +2938,34 @@ fn nullLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError...@@ -2856,34 +2938,34 @@ fn nullLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError
2856 const tree = scope.tree();2938 const tree = scope.tree();
2857 const node_datas = tree.nodes.items(.data);2939 const node_datas = tree.nodes.items(.data);
2858 const main_tokens = tree.nodes.items(.main_token);2940 const main_tokens = tree.nodes.items(.main_token);
2859 const src = tree.token_locs[node.token].start;2941 const src = token_starts[node.token];
2860 return addZIRInstConst(mod, scope, src, .{2942 return addZIRInstConst(mod, scope, src, .{
2861 .ty = Type.initTag(.@"null"),2943 .ty = Type.initTag(.@"null"),
2862 .val = Value.initTag(.null_value),2944 .val = Value.initTag(.null_value),
2863 });2945 });
2864}2946}
28652947
2866fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.@"asm") InnerError!*zir.Inst {2948fn assembly(mod: *Module, scope: *Scope, rl: ResultLoc, full: ast.full.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 }
2870 const arena = scope.arena();2949 const arena = scope.arena();
2871 const tree = scope.tree();2950 const tree = scope.tree();
2872 const node_datas = tree.nodes.items(.data);2951 const node_datas = tree.nodes.items(.data);
2873 const main_tokens = tree.nodes.items(.main_token);2952 const main_tokens = tree.nodes.items(.main_token);
28742953
2875 const inputs = try arena.alloc(*zir.Inst, asm_node.inputs.len);2954 if (full.outputs.len != 0) {
2876 const args = try arena.alloc(*zir.Inst, asm_node.inputs.len);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];
2880 const str_type = try addZIRInstConst(mod, scope, src, .{2962 const str_type = try addZIRInstConst(mod, scope, src, .{
2881 .ty = Type.initTag(.type),2963 .ty = Type.initTag(.type),
2882 .val = Value.initTag(.const_slice_u8_type),2964 .val = Value.initTag(.const_slice_u8_type),
2883 });2965 });
2884 const str_type_rl: ResultLoc = .{ .ty = str_type };2966 const str_type_rl: ResultLoc = .{ .ty = str_type };
28852967
2886 for (asm_node.inputs) |input, i| {2968 for (full.inputs) |input, i| {
2887 // TODO semantically analyze constraints2969 // TODO semantically analyze constraints
2888 inputs[i] = try expr(mod, scope, str_type_rl, input.constraint);2970 inputs[i] = try expr(mod, scope, str_type_rl, input.constraint);
2889 args[i] = try expr(mod, scope, .none, input.expr);2971 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!...@@ -2894,15 +2976,15 @@ fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.@"asm") InnerError!
2894 .val = Value.initTag(.void_type),2976 .val = Value.initTag(.void_type),
2895 });2977 });
2896 const asm_inst = try addZIRInst(mod, scope, src, zir.Inst.@"asm", .{2978 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),
2898 .return_type = return_type,2980 .return_type = return_type,
2899 }, .{2981 }, .{
2900 .@"volatile" = asm_node.volatile_token != null,2982 .@"volatile" = full.volatile_token != null,
2901 //.clobbers = TODO handle clobbers2983 //.clobbers = TODO handle clobbers
2902 .inputs = inputs,2984 .inputs = inputs,
2903 .args = args,2985 .args = args,
2904 });2986 });
2905 return asm_inst;2987 return rvalue(mod, scope, rl, asm_inst);
2906}2988}
29072989
2908fn ensureBuiltinParamCount(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call, count: u32) !void {2990fn ensureBuiltinParamCount(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call, count: u32) !void {
...@@ -2924,7 +3006,7 @@ fn simpleCast(...@@ -2924,7 +3006,7 @@ fn simpleCast(
2924 const tree = scope.tree();3006 const tree = scope.tree();
2925 const node_datas = tree.nodes.items(.data);3007 const node_datas = tree.nodes.items(.data);
2926 const main_tokens = tree.nodes.items(.main_token);3008 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];
2928 const params = call.params();3010 const params = call.params();
2929 const dest_type = try typeExpr(mod, scope, params[0]);3011 const dest_type = try typeExpr(mod, scope, params[0]);
2930 const rhs = try expr(mod, scope, .none, params[1]);3012 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...@@ -2938,7 +3020,7 @@ fn ptrToInt(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerErro
2938 const tree = scope.tree();3020 const tree = scope.tree();
2939 const node_datas = tree.nodes.items(.data);3021 const node_datas = tree.nodes.items(.data);
2940 const main_tokens = tree.nodes.items(.main_token);3022 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];
2942 return addZIRUnOp(mod, scope, src, .ptrtoint, operand);3024 return addZIRUnOp(mod, scope, src, .ptrtoint, operand);
2943}3025}
29443026
...@@ -2952,7 +3034,7 @@ fn as(...@@ -2952,7 +3034,7 @@ fn as(
2952 const tree = scope.tree();3034 const tree = scope.tree();
2953 const node_datas = tree.nodes.items(.data);3035 const node_datas = tree.nodes.items(.data);
2954 const main_tokens = tree.nodes.items(.main_token);3036 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];
2956 const params = call.params();3038 const params = call.params();
2957 const dest_type = try typeExpr(mod, scope, params[0]);3039 const dest_type = try typeExpr(mod, scope, params[0]);
2958 switch (rl) {3040 switch (rl) {
...@@ -3028,7 +3110,7 @@ fn bitCast(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.builtin_c...@@ -3028,7 +3110,7 @@ fn bitCast(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.builtin_c
3028 const tree = scope.tree();3110 const tree = scope.tree();
3029 const node_datas = tree.nodes.items(.data);3111 const node_datas = tree.nodes.items(.data);
3030 const main_tokens = tree.nodes.items(.main_token);3112 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];
3032 const params = call.params();3114 const params = call.params();
3033 const dest_type = try typeExpr(mod, scope, params[0]);3115 const dest_type = try typeExpr(mod, scope, params[0]);
3034 switch (rl) {3116 switch (rl) {
...@@ -3074,7 +3156,7 @@ fn import(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerError!...@@ -3074,7 +3156,7 @@ fn import(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerError!
3074 const tree = scope.tree();3156 const tree = scope.tree();
3075 const node_datas = tree.nodes.items(.data);3157 const node_datas = tree.nodes.items(.data);
3076 const main_tokens = tree.nodes.items(.main_token);3158 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];
3078 const params = call.params();3160 const params = call.params();
3079 const target = try expr(mod, scope, .none, params[0]);3161 const target = try expr(mod, scope, .none, params[0]);
3080 return addZIRUnOp(mod, scope, src, .import, target);3162 return addZIRUnOp(mod, scope, src, .import, target);
...@@ -3085,7 +3167,7 @@ fn compileError(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) Inner...@@ -3085,7 +3167,7 @@ fn compileError(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) Inner
3085 const tree = scope.tree();3167 const tree = scope.tree();
3086 const node_datas = tree.nodes.items(.data);3168 const node_datas = tree.nodes.items(.data);
3087 const main_tokens = tree.nodes.items(.main_token);3169 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];
3089 const params = call.params();3171 const params = call.params();
3090 const target = try expr(mod, scope, .none, params[0]);3172 const target = try expr(mod, scope, .none, params[0]);
3091 return addZIRUnOp(mod, scope, src, .compile_error, target);3173 return addZIRUnOp(mod, scope, src, .compile_error, target);
...@@ -3096,7 +3178,7 @@ fn setEvalBranchQuota(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call)...@@ -3096,7 +3178,7 @@ fn setEvalBranchQuota(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call)
3096 const tree = scope.tree();3178 const tree = scope.tree();
3097 const node_datas = tree.nodes.items(.data);3179 const node_datas = tree.nodes.items(.data);
3098 const main_tokens = tree.nodes.items(.main_token);3180 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];
3100 const params = call.params();3182 const params = call.params();
3101 const u32_type = try addZIRInstConst(mod, scope, src, .{3183 const u32_type = try addZIRInstConst(mod, scope, src, .{
3102 .ty = Type.initTag(.type),3184 .ty = Type.initTag(.type),
...@@ -3111,7 +3193,7 @@ fn typeOf(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.builtin_ca...@@ -3111,7 +3193,7 @@ fn typeOf(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.builtin_ca
3111 const node_datas = tree.nodes.items(.data);3193 const node_datas = tree.nodes.items(.data);
3112 const main_tokens = tree.nodes.items(.main_token);3194 const main_tokens = tree.nodes.items(.main_token);
3113 const arena = scope.arena();3195 const arena = scope.arena();
3114 const src = tree.token_locs[call.builtin_token].start;3196 const src = token_starts[call.builtin_token];
3115 const params = call.params();3197 const params = call.params();
3116 if (params.len < 1) {3198 if (params.len < 1) {
3117 return mod.failTok(scope, call.builtin_token, "expected at least 1 argument, found 0", .{});3199 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...@@ -3129,7 +3211,7 @@ fn compileLog(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerEr
3129 const node_datas = tree.nodes.items(.data);3211 const node_datas = tree.nodes.items(.data);
3130 const main_tokens = tree.nodes.items(.main_token);3212 const main_tokens = tree.nodes.items(.main_token);
3131 const arena = scope.arena();3213 const arena = scope.arena();
3132 const src = tree.token_locs[call.builtin_token].start;3214 const src = token_starts[call.builtin_token];
3133 const params = call.params();3215 const params = call.params();
3134 var targets = try arena.alloc(*zir.Inst, params.len);3216 var targets = try arena.alloc(*zir.Inst, params.len);
3135 for (params) |param, param_i|3217 for (params) |param, param_i|
...@@ -3161,7 +3243,7 @@ fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.built...@@ -3161,7 +3243,7 @@ fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.built
3161 } else if (mem.eql(u8, builtin_name, "@TypeOf")) {3243 } else if (mem.eql(u8, builtin_name, "@TypeOf")) {
3162 return typeOf(mod, scope, rl, call);3244 return typeOf(mod, scope, rl, call);
3163 } else if (mem.eql(u8, builtin_name, "@breakpoint")) {3245 } 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];
3165 return rvalue(mod, scope, rl, try addZIRNoOp(mod, scope, src, .breakpoint));3247 return rvalue(mod, scope, rl, try addZIRNoOp(mod, scope, src, .breakpoint));
3166 } else if (mem.eql(u8, builtin_name, "@import")) {3248 } else if (mem.eql(u8, builtin_name, "@import")) {
3167 return rvalue(mod, scope, rl, try import(mod, scope, call));3249 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...@@ -3187,7 +3269,7 @@ fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.call) In
3187 const param_nodes = node.params();3269 const param_nodes = node.params();
3188 const args = try scope.getGenZIR().arena.alloc(*zir.Inst, param_nodes.len);3270 const args = try scope.getGenZIR().arena.alloc(*zir.Inst, param_nodes.len);
3189 for (param_nodes) |param_node, i| {3271 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)];
3191 const param_type = try addZIRInst(mod, scope, param_src, zir.Inst.ParamType, .{3273 const param_type = try addZIRInst(mod, scope, param_src, zir.Inst.ParamType, .{
3192 .func = lhs,3274 .func = lhs,
3193 .arg_index = i,3275 .arg_index = i,
...@@ -3195,7 +3277,7 @@ fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.call) In...@@ -3195,7 +3277,7 @@ fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.call) In
3195 args[i] = try expr(mod, scope, .{ .ty = param_type }, param_node);3277 args[i] = try expr(mod, scope, .{ .ty = param_type }, param_node);
3196 }3278 }
31973279
3198 const src = tree.token_locs[node.lhs.firstToken()].start;3280 const src = token_starts[node.lhs.firstToken()];
3199 const result = try addZIRInst(mod, scope, src, zir.Inst.Call, .{3281 const result = try addZIRInst(mod, scope, src, zir.Inst.Call, .{
3200 .func = lhs,3282 .func = lhs,
3201 .args = args,3283 .args = args,
...@@ -3208,7 +3290,7 @@ fn unreach(mod: *Module, scope: *Scope, unreach_node: *ast.Node.OneToken) InnerE...@@ -3208,7 +3290,7 @@ fn unreach(mod: *Module, scope: *Scope, unreach_node: *ast.Node.OneToken) InnerE
3208 const tree = scope.tree();3290 const tree = scope.tree();
3209 const node_datas = tree.nodes.items(.data);3291 const node_datas = tree.nodes.items(.data);
3210 const main_tokens = tree.nodes.items(.main_token);3292 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];
3212 return addZIRNoOp(mod, scope, src, .unreachable_safe);3294 return addZIRNoOp(mod, scope, src, .unreachable_safe);
3213}3295}
32143296
...@@ -3528,6 +3610,8 @@ fn rvalue(mod: *Module, scope: *Scope, rl: ResultLoc, result: *zir.Inst) InnerEr...@@ -3528,6 +3610,8 @@ fn rvalue(mod: *Module, scope: *Scope, rl: ResultLoc, result: *zir.Inst) InnerEr
3528 }3610 }
3529}3611}
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.
3531fn rvalueVoid(3615fn rvalueVoid(
3532 mod: *Module,3616 mod: *Module,
3533 scope: *Scope,3617 scope: *Scope,