| ... | ... | @@ -56,7 +56,8 @@ pub const ResultLoc = union(enum) { |
| 56 | 56 | }; |
| 57 | 57 | |
| 58 | 58 | pub 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 | 61 | const type_type = try addZIRInstConst(mod, scope, type_src, .{ |
| 61 | 62 | .ty = Type.initTag(.type), |
| 62 | 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 | 259 | .array_cat => return simpleBinOp(mod, scope, rl, node, .array_cat), |
| 259 | 260 | .array_mult => return simpleBinOp(mod, scope, rl, node, .array_mul), |
| 260 | 261 | |
| 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), |
| 263 | 264 | |
| 264 | 265 | .bool_not => return rvalue(mod, scope, rl, try boolNot(mod, scope, node)), |
| 265 | 266 | .bit_not => return rvalue(mod, scope, rl, try bitNot(mod, scope, node)), |
| 266 | 267 | .negation => return rvalue(mod, scope, rl, try negation(mod, scope, node, .sub)), |
| 267 | 268 | .negation_wrap => return rvalue(mod, scope, rl, try negation(mod, scope, node, .subwrap)), |
| 268 | 269 | |
| 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), |
| 273 | 279 | .builtin_call => return builtinCall(mod, scope, rl, node), |
| 274 | 280 | .call => return callExpr(mod, scope, rl, node), |
| 275 | 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 | 291 | .null_literal => return rvalue(mod, scope, rl, try nullLiteral(mod, scope, node)), |
| 286 | 292 | .optional_type => return rvalue(mod, scope, rl, try optionalType(mod, scope, node)), |
| 287 | 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 | 310 | .labeled_block => return labeledBlockExpr(mod, scope, rl, node, .block), |
| 290 | 311 | .@"break" => return rvalue(mod, scope, rl, try breakExpr(mod, scope, node)), |
| 291 | 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 | 314 | .array_type => return rvalue(mod, scope, rl, try arrayType(mod, scope, node)), |
| 294 | 315 | .array_type_sentinel => return rvalue(mod, scope, rl, try arrayTypeSentinel(mod, scope, node)), |
| 295 | 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 | 317 | .char_literal => return rvalue(mod, scope, rl, try charLiteral(mod, scope, node)), |
| 298 | 318 | .slice_type => return rvalue(mod, scope, rl, try sliceType(mod, scope, node)), |
| 299 | 319 | .error_union => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node, .error_union_type)), |
| ... | ... | @@ -343,10 +363,17 @@ pub fn comptimeExpr( |
| 343 | 363 | return expr(mod, parent_scope, rl, node); |
| 344 | 364 | } |
| 345 | 365 | |
| 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 | 370 | // Optimization for labeled blocks: don't need to have 2 layers of blocks, |
| 347 | 371 | // 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); |
| 350 | 377 | } |
| 351 | 378 | |
| 352 | 379 | // Make a scope to collect generated instructions in the sub-expression. |
| ... | ... | @@ -363,11 +390,7 @@ pub fn comptimeExpr( |
| 363 | 390 | // instruction is the block's result value. |
| 364 | 391 | _ = try expr(mod, &block_scope.base, rl, node); |
| 365 | 392 | |
| 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)]; |
| 371 | 394 | const block = try addZIRInstBlock(mod, parent_scope, src, .block_comptime_flat, .{ |
| 372 | 395 | .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items), |
| 373 | 396 | }); |
| ... | ... | @@ -375,15 +398,13 @@ pub fn comptimeExpr( |
| 375 | 398 | return &block.base; |
| 376 | 399 | } |
| 377 | 400 | |
| 378 | | fn breakExpr( |
| 379 | | mod: *Module, |
| 380 | | parent_scope: *Scope, |
| 381 | | node: *ast.Node.ControlFlowExpression, |
| 382 | | ) InnerError!*zir.Inst { |
| 401 | fn breakExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst { |
| 383 | 402 | const tree = parent_scope.tree(); |
| 384 | 403 | const node_datas = tree.nodes.items(.data); |
| 385 | 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; |
| 387 | 408 | |
| 388 | 409 | // Look for the label in the scope. |
| 389 | 410 | var scope = parent_scope; |
| ... | ... | @@ -393,7 +414,7 @@ fn breakExpr( |
| 393 | 414 | const gen_zir = scope.cast(Scope.GenZIR).?; |
| 394 | 415 | |
| 395 | 416 | const block_inst = blk: { |
| 396 | | if (node.getLabel()) |break_label| { |
| 417 | if (break_label != 0) { |
| 397 | 418 | if (gen_zir.label) |*label| { |
| 398 | 419 | if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) { |
| 399 | 420 | label.used = true; |
| ... | ... | @@ -407,11 +428,11 @@ fn breakExpr( |
| 407 | 428 | continue; |
| 408 | 429 | }; |
| 409 | 430 | |
| 410 | | const rhs = node.getRHS() orelse { |
| 431 | if (rhs == 0) { |
| 411 | 432 | return addZirInstTag(mod, parent_scope, src, .break_void, .{ |
| 412 | 433 | .block = block_inst, |
| 413 | 434 | }); |
| 414 | | }; |
| 435 | } |
| 415 | 436 | gen_zir.break_count += 1; |
| 416 | 437 | const prev_rvalue_rl_count = gen_zir.rvalue_rl_count; |
| 417 | 438 | const operand = try expr(mod, parent_scope, gen_zir.break_result_loc, rhs); |
| ... | ... | @@ -435,7 +456,7 @@ fn breakExpr( |
| 435 | 456 | }, |
| 436 | 457 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 437 | 458 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| 438 | | else => if (node.getLabel()) |break_label| { |
| 459 | else => if (break_label != 0) { |
| 439 | 460 | const label_name = try mod.identifierTokenString(parent_scope, break_label); |
| 440 | 461 | return mod.failTok(parent_scope, break_label, "label not found: '{s}'", .{label_name}); |
| 441 | 462 | } else { |
| ... | ... | @@ -445,11 +466,12 @@ fn breakExpr( |
| 445 | 466 | } |
| 446 | 467 | } |
| 447 | 468 | |
| 448 | | fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowExpression) InnerError!*zir.Inst { |
| 469 | fn continueExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst { |
| 449 | 470 | const tree = parent_scope.tree(); |
| 450 | 471 | const node_datas = tree.nodes.items(.data); |
| 451 | 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; |
| 453 | 475 | |
| 454 | 476 | // Look for the label in the scope. |
| 455 | 477 | var scope = parent_scope; |
| ... | ... | @@ -461,7 +483,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE |
| 461 | 483 | scope = gen_zir.parent; |
| 462 | 484 | continue; |
| 463 | 485 | }; |
| 464 | | if (node.getLabel()) |break_label| blk: { |
| 486 | if (break_label != 0) blk: { |
| 465 | 487 | if (gen_zir.label) |*label| { |
| 466 | 488 | if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) { |
| 467 | 489 | label.used = true; |
| ... | ... | @@ -479,7 +501,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE |
| 479 | 501 | }, |
| 480 | 502 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 481 | 503 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| 482 | | else => if (node.getLabel()) |break_label| { |
| 504 | else => if (break_label != 0) { |
| 483 | 505 | const label_name = try mod.identifierTokenString(parent_scope, break_label); |
| 484 | 506 | return mod.failTok(parent_scope, break_label, "label not found: '{s}'", .{label_name}); |
| 485 | 507 | } else { |
| ... | ... | @@ -489,11 +511,18 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE |
| 489 | 511 | } |
| 490 | 512 | } |
| 491 | 513 | |
| 492 | | pub fn blockExpr(mod: *Module, parent_scope: *Scope, block_node: *ast.Node.block) InnerError!void { |
| 514 | pub 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 | 521 | const tracy = trace(@src()); |
| 494 | 522 | defer tracy.end(); |
| 495 | 523 | |
| 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 | } |
| 498 | 527 | |
| 499 | 528 | fn 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 | 537 | const tree = parent_scope.tree(); |
| 509 | 538 | const node_datas = tree.nodes.items(.data); |
| 510 | 539 | 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]; |
| 513 | 542 | |
| 514 | 543 | const label_name = try mod.identifierTokenString(parent_scope, label); |
| 515 | 544 | const msg = msg: { |
| ... | ... | @@ -556,7 +585,7 @@ fn labeledBlockExpr( |
| 556 | 585 | const tree = parent_scope.tree(); |
| 557 | 586 | const node_datas = tree.nodes.items(.data); |
| 558 | 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]; |
| 560 | 589 | |
| 561 | 590 | try checkLabelRedefinition(mod, parent_scope, block_node.label); |
| 562 | 591 | |
| ... | ... | @@ -595,7 +624,7 @@ fn labeledBlockExpr( |
| 595 | 624 | try blockExprStmts(mod, &block_scope.base, &block_node.base, block_node.statements()); |
| 596 | 625 | |
| 597 | 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 | } |
| 600 | 629 | |
| 601 | 630 | try gen_zir.instructions.append(mod.gpa, &block_inst.base); |
| ... | ... | @@ -647,7 +676,7 @@ fn blockExprStmts( |
| 647 | 676 | |
| 648 | 677 | var scope = parent_scope; |
| 649 | 678 | for (statements) |statement| { |
| 650 | | const src = tree.token_locs[statement.firstToken()].start; |
| 679 | const src = token_starts[statement.firstToken()]; |
| 651 | 680 | _ = try addZIRNoOp(mod, scope, src, .dbg_stmt); |
| 652 | 681 | switch (statement.tag) { |
| 653 | 682 | .var_decl => { |
| ... | ... | @@ -694,7 +723,7 @@ fn varDecl( |
| 694 | 723 | const tree = scope.tree(); |
| 695 | 724 | const node_datas = tree.nodes.items(.data); |
| 696 | 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 | 727 | const ident_name = try mod.identifierTokenString(scope, node.name_token); |
| 699 | 728 | |
| 700 | 729 | // Local variables shadowing detection, including function parameters. |
| ... | ... | @@ -911,34 +940,46 @@ fn assignOp( |
| 911 | 940 | _ = try addZIRBinOp(mod, scope, src, .store, lhs_ptr, result); |
| 912 | 941 | } |
| 913 | 942 | |
| 914 | | fn boolNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst { |
| 943 | fn boolNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst { |
| 915 | 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 | 949 | const bool_type = try addZIRInstConst(mod, scope, src, .{ |
| 918 | 950 | .ty = Type.initTag(.type), |
| 919 | 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 | 954 | return addZIRUnOp(mod, scope, src, .bool_not, operand); |
| 923 | 955 | } |
| 924 | 956 | |
| 925 | | fn bitNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst { |
| 957 | fn bitNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst { |
| 926 | 958 | 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); |
| 929 | 964 | return addZIRUnOp(mod, scope, src, .bit_not, operand); |
| 930 | 965 | } |
| 931 | 966 | |
| 932 | | fn negation(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp, op_inst_tag: zir.Inst.Tag) InnerError!*zir.Inst { |
| 967 | fn negation( |
| 968 | mod: *Module, |
| 969 | scope: *Scope, |
| 970 | node: ast.Node.Index, |
| 971 | op_inst_tag: zir.Inst.Tag, |
| 972 | ) InnerError!*zir.Inst { |
| 933 | 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); |
| 935 | 976 | |
| 977 | const src = token_starts[main_tokens[node]]; |
| 936 | 978 | const lhs = try addZIRInstConst(mod, scope, src, .{ |
| 937 | 979 | .ty = Type.initTag(.comptime_int), |
| 938 | 980 | .val = Value.initTag(.zero), |
| 939 | 981 | }); |
| 940 | | const rhs = try expr(mod, scope, .none, node.rhs); |
| 941 | | |
| 982 | const rhs = try expr(mod, scope, .none, node_datas[node].lhs); |
| 942 | 983 | return addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs); |
| 943 | 984 | } |
| 944 | 985 | |
| ... | ... | @@ -948,20 +989,20 @@ fn addressOf(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerE |
| 948 | 989 | |
| 949 | 990 | fn optionalType(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst { |
| 950 | 991 | const tree = scope.tree(); |
| 951 | | const src = tree.token_locs[node.op_token].start; |
| 992 | const src = token_starts[node.op_token]; |
| 952 | 993 | const operand = try typeExpr(mod, scope, node.rhs); |
| 953 | 994 | return addZIRUnOp(mod, scope, src, .optional_type, operand); |
| 954 | 995 | } |
| 955 | 996 | |
| 956 | 997 | fn sliceType(mod: *Module, scope: *Scope, node: *ast.Node.slice_type) InnerError!*zir.Inst { |
| 957 | 998 | const tree = scope.tree(); |
| 958 | | const src = tree.token_locs[node.op_token].start; |
| 999 | const src = token_starts[node.op_token]; |
| 959 | 1000 | return ptrSliceType(mod, scope, src, &node.ptr_info, node.rhs, .Slice); |
| 960 | 1001 | } |
| 961 | 1002 | |
| 962 | 1003 | fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir.Inst { |
| 963 | 1004 | const tree = scope.tree(); |
| 964 | | const src = tree.token_locs[node.op_token].start; |
| 1005 | const src = token_starts[node.op_token]; |
| 965 | 1006 | return ptrSliceType(mod, scope, src, &node.ptr_info, node.rhs, switch (tree.token_ids[node.op_token]) { |
| 966 | 1007 | .Asterisk, .AsteriskAsterisk => .One, |
| 967 | 1008 | // TODO stage1 type inference bug |
| ... | ... | @@ -1018,7 +1059,7 @@ fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo, |
| 1018 | 1059 | |
| 1019 | 1060 | fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.array_type) !*zir.Inst { |
| 1020 | 1061 | const tree = scope.tree(); |
| 1021 | | const src = tree.token_locs[node.op_token].start; |
| 1062 | const src = token_starts[node.op_token]; |
| 1022 | 1063 | const usize_type = try addZIRInstConst(mod, scope, src, .{ |
| 1023 | 1064 | .ty = Type.initTag(.type), |
| 1024 | 1065 | .val = Value.initTag(.usize_type), |
| ... | ... | @@ -1033,7 +1074,7 @@ fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.array_type) !*zir.Inst |
| 1033 | 1074 | |
| 1034 | 1075 | fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.array_type_sentinel) !*zir.Inst { |
| 1035 | 1076 | const tree = scope.tree(); |
| 1036 | | const src = tree.token_locs[node.op_token].start; |
| 1077 | const src = token_starts[node.op_token]; |
| 1037 | 1078 | const usize_type = try addZIRInstConst(mod, scope, src, .{ |
| 1038 | 1079 | .ty = Type.initTag(.type), |
| 1039 | 1080 | .val = Value.initTag(.usize_type), |
| ... | ... | @@ -1054,7 +1095,7 @@ fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.array_type_sen |
| 1054 | 1095 | |
| 1055 | 1096 | fn anyFrameType(mod: *Module, scope: *Scope, node: *ast.Node.anyframe_type) InnerError!*zir.Inst { |
| 1056 | 1097 | const tree = scope.tree(); |
| 1057 | | const src = tree.token_locs[node.anyframe_token].start; |
| 1098 | const src = token_starts[node.anyframe_token]; |
| 1058 | 1099 | if (node.result) |some| { |
| 1059 | 1100 | const return_type = try typeExpr(mod, scope, some.return_type); |
| 1060 | 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 | 1109 | |
| 1069 | 1110 | fn typeInixOp(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp, op_inst_tag: zir.Inst.Tag) InnerError!*zir.Inst { |
| 1070 | 1111 | const tree = scope.tree(); |
| 1071 | | const src = tree.token_locs[node.op_token].start; |
| 1112 | const src = token_starts[node.op_token]; |
| 1072 | 1113 | const error_set = try typeExpr(mod, scope, node.lhs); |
| 1073 | 1114 | const payload = try typeExpr(mod, scope, node.rhs); |
| 1074 | 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 | 1117 | |
| 1077 | 1118 | fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.enum_literal) !*zir.Inst { |
| 1078 | 1119 | const tree = scope.tree(); |
| 1079 | | const src = tree.token_locs[node.name].start; |
| 1120 | const src = token_starts[node.name]; |
| 1080 | 1121 | const name = try mod.identifierTokenString(scope, node.name); |
| 1081 | 1122 | |
| 1082 | 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 | 1125 | |
| 1085 | 1126 | fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst { |
| 1086 | 1127 | const tree = scope.tree(); |
| 1087 | | const src = tree.token_locs[node.rtoken].start; |
| 1128 | const src = token_starts[node.rtoken]; |
| 1088 | 1129 | |
| 1089 | 1130 | const operand = try expr(mod, scope, rl, node.lhs); |
| 1090 | 1131 | const op: zir.Inst.Tag = switch (rl) { |
| ... | ... | @@ -1100,7 +1141,7 @@ fn containerField( |
| 1100 | 1141 | node: *ast.Node.ContainerField, |
| 1101 | 1142 | ) InnerError!*zir.Inst { |
| 1102 | 1143 | const tree = scope.tree(); |
| 1103 | | const src = tree.token_locs[node.firstToken()].start; |
| 1144 | const src = token_starts[tree.firstToken(node)]; |
| 1104 | 1145 | const name = try mod.identifierTokenString(scope, node.name_token); |
| 1105 | 1146 | |
| 1106 | 1147 | if (node.comptime_token == null and node.value_expr == null and node.align_expr == null) { |
| ... | ... | @@ -1133,7 +1174,7 @@ fn containerField( |
| 1133 | 1174 | |
| 1134 | 1175 | fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.ContainerDecl) InnerError!*zir.Inst { |
| 1135 | 1176 | const tree = scope.tree(); |
| 1136 | | const src = tree.token_locs[node.kind_token].start; |
| 1177 | const src = token_starts[node.kind_token]; |
| 1137 | 1178 | |
| 1138 | 1179 | var gen_scope: Scope.GenZIR = .{ |
| 1139 | 1180 | .parent = scope, |
| ... | ... | @@ -1278,7 +1319,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con |
| 1278 | 1319 | |
| 1279 | 1320 | fn errorSetDecl(mod: *Module, scope: *Scope, node: *ast.Node.error_set_decl) InnerError!*zir.Inst { |
| 1280 | 1321 | const tree = scope.tree(); |
| 1281 | | const src = tree.token_locs[node.error_token].start; |
| 1322 | const src = token_starts[node.error_token]; |
| 1282 | 1323 | const decls = node.decls(); |
| 1283 | 1324 | const fields = try scope.arena().alloc([]const u8, decls.len); |
| 1284 | 1325 | |
| ... | ... | @@ -1292,7 +1333,7 @@ fn errorSetDecl(mod: *Module, scope: *Scope, node: *ast.Node.error_set_decl) Inn |
| 1292 | 1333 | |
| 1293 | 1334 | fn errorType(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst { |
| 1294 | 1335 | const tree = scope.tree(); |
| 1295 | | const src = tree.token_locs[node.token].start; |
| 1336 | const src = token_starts[node.token]; |
| 1296 | 1337 | return addZIRInstConst(mod, scope, src, .{ |
| 1297 | 1338 | .ty = Type.initTag(.type), |
| 1298 | 1339 | .val = Value.initTag(.anyerror_type), |
| ... | ... | @@ -1370,7 +1411,7 @@ fn orelseCatchExpr( |
| 1370 | 1411 | payload_node: ?*ast.Node, |
| 1371 | 1412 | ) InnerError!*zir.Inst { |
| 1372 | 1413 | const tree = scope.tree(); |
| 1373 | | const src = tree.token_locs[op_token].start; |
| 1414 | const src = token_starts[op_token]; |
| 1374 | 1415 | |
| 1375 | 1416 | var block_scope: Scope.GenZIR = .{ |
| 1376 | 1417 | .parent = scope, |
| ... | ... | @@ -1544,7 +1585,7 @@ fn tokenIdentEql(mod: *Module, scope: *Scope, token1: ast.TokenIndex, token2: as |
| 1544 | 1585 | |
| 1545 | 1586 | pub fn field(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleInfixOp) InnerError!*zir.Inst { |
| 1546 | 1587 | const tree = scope.tree(); |
| 1547 | | const src = tree.token_locs[node.op_token].start; |
| 1588 | const src = token_starts[node.op_token]; |
| 1548 | 1589 | // TODO custom AST node for field access so that we don't have to go through a node cast here |
| 1549 | 1590 | const field_name = try mod.identifierTokenString(scope, node.rhs.castTag(.identifier).?.token); |
| 1550 | 1591 | if (rl == .ref) { |
| ... | ... | @@ -1568,7 +1609,7 @@ fn namedField( |
| 1568 | 1609 | try ensureBuiltinParamCount(mod, scope, call, 2); |
| 1569 | 1610 | |
| 1570 | 1611 | const tree = scope.tree(); |
| 1571 | | const src = tree.token_locs[call.builtin_token].start; |
| 1612 | const src = token_starts[call.builtin_token]; |
| 1572 | 1613 | const params = call.params(); |
| 1573 | 1614 | |
| 1574 | 1615 | const string_type = try addZIRInstConst(mod, scope, src, .{ |
| ... | ... | @@ -1591,7 +1632,7 @@ fn namedField( |
| 1591 | 1632 | |
| 1592 | 1633 | fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.array_access) InnerError!*zir.Inst { |
| 1593 | 1634 | const tree = scope.tree(); |
| 1594 | | const src = tree.token_locs[node.rtoken].start; |
| 1635 | const src = token_starts[node.rtoken]; |
| 1595 | 1636 | const usize_type = try addZIRInstConst(mod, scope, src, .{ |
| 1596 | 1637 | .ty = Type.initTag(.type), |
| 1597 | 1638 | .val = Value.initTag(.usize_type), |
| ... | ... | @@ -1612,7 +1653,7 @@ fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.array |
| 1612 | 1653 | |
| 1613 | 1654 | fn sliceExpr(mod: *Module, scope: *Scope, node: *ast.Node.slice) InnerError!*zir.Inst { |
| 1614 | 1655 | const tree = scope.tree(); |
| 1615 | | const src = tree.token_locs[node.rtoken].start; |
| 1656 | const src = token_starts[node.rtoken]; |
| 1616 | 1657 | |
| 1617 | 1658 | const usize_type = try addZIRInstConst(mod, scope, src, .{ |
| 1618 | 1659 | .ty = Type.initTag(.type), |
| ... | ... | @@ -1642,7 +1683,7 @@ fn sliceExpr(mod: *Module, scope: *Scope, node: *ast.Node.slice) InnerError!*zir |
| 1642 | 1683 | |
| 1643 | 1684 | fn deref(mod: *Module, scope: *Scope, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst { |
| 1644 | 1685 | const tree = scope.tree(); |
| 1645 | | const src = tree.token_locs[node.rtoken].start; |
| 1686 | const src = token_starts[node.rtoken]; |
| 1646 | 1687 | const lhs = try expr(mod, scope, .none, node.lhs); |
| 1647 | 1688 | return addZIRUnOp(mod, scope, src, .deref, lhs); |
| 1648 | 1689 | } |
| ... | ... | @@ -1669,13 +1710,14 @@ fn boolBinOp( |
| 1669 | 1710 | mod: *Module, |
| 1670 | 1711 | scope: *Scope, |
| 1671 | 1712 | rl: ResultLoc, |
| 1672 | | infix_node: *ast.Node.SimpleInfixOp, |
| 1713 | infix_node: ast.Node.Index, |
| 1714 | is_bool_and: bool, |
| 1673 | 1715 | ) InnerError!*zir.Inst { |
| 1674 | 1716 | const tree = scope.tree(); |
| 1675 | 1717 | const node_datas = tree.nodes.items(.data); |
| 1676 | 1718 | const main_tokens = tree.nodes.items(.main_token); |
| 1677 | 1719 | |
| 1678 | | const src = tree.token_locs[infix_node.op_token].start; |
| 1720 | const src = token_starts[main_tokens[infix_node]]; |
| 1679 | 1721 | const bool_type = try addZIRInstConst(mod, scope, src, .{ |
| 1680 | 1722 | .ty = Type.initTag(.type), |
| 1681 | 1723 | .val = Value.initTag(.bool_type), |
| ... | ... | @@ -1690,7 +1732,7 @@ fn boolBinOp( |
| 1690 | 1732 | }; |
| 1691 | 1733 | defer block_scope.instructions.deinit(mod.gpa); |
| 1692 | 1734 | |
| 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 | 1736 | const condbr = try addZIRInstSpecial(mod, &block_scope.base, src, zir.Inst.CondBr, .{ |
| 1695 | 1737 | .condition = lhs, |
| 1696 | 1738 | .then_body = undefined, // populated below |
| ... | ... | @@ -1710,7 +1752,7 @@ fn boolBinOp( |
| 1710 | 1752 | }; |
| 1711 | 1753 | defer rhs_scope.instructions.deinit(mod.gpa); |
| 1712 | 1754 | |
| 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 | 1756 | _ = try addZIRInst(mod, &rhs_scope.base, src, zir.Inst.Break, .{ |
| 1715 | 1757 | .block = block, |
| 1716 | 1758 | .operand = rhs, |
| ... | ... | @@ -1725,7 +1767,6 @@ fn boolBinOp( |
| 1725 | 1767 | }; |
| 1726 | 1768 | defer const_scope.instructions.deinit(mod.gpa); |
| 1727 | 1769 | |
| 1728 | | const is_bool_and = infix_node.base.tag == .bool_and; |
| 1729 | 1770 | _ = try addZIRInst(mod, &const_scope.base, src, zir.Inst.Break, .{ |
| 1730 | 1771 | .block = block, |
| 1731 | 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 | 1884 | const tree = scope.tree(); |
| 1844 | 1885 | const node_datas = tree.nodes.items(.data); |
| 1845 | 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 | 1888 | const cond = try cond_kind.cond(mod, &block_scope, if_src, if_node.condition); |
| 1848 | 1889 | |
| 1849 | 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 | 1897 | .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items), |
| 1857 | 1898 | }); |
| 1858 | 1899 | |
| 1859 | | const then_src = tree.token_locs[if_node.body.lastToken()].start; |
| 1900 | const then_src = token_starts[if_node.body.lastToken()]; |
| 1860 | 1901 | var then_scope: Scope.GenZIR = .{ |
| 1861 | 1902 | .parent = scope, |
| 1862 | 1903 | .decl = block_scope.decl, |
| ... | ... | @@ -1887,14 +1928,14 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.@"if") |
| 1887 | 1928 | var else_src: usize = undefined; |
| 1888 | 1929 | var else_sub_scope: *Module.Scope = undefined; |
| 1889 | 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 | 1932 | // declare payload to the then_scope |
| 1892 | 1933 | else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload); |
| 1893 | 1934 | |
| 1894 | 1935 | block_scope.break_count += 1; |
| 1895 | 1936 | break :blk try expr(mod, else_sub_scope, block_scope.break_result_loc, else_node.body); |
| 1896 | 1937 | } else blk: { |
| 1897 | | else_src = tree.token_locs[if_node.lastToken()].start; |
| 1938 | else_src = token_starts[if_node.lastToken()]; |
| 1898 | 1939 | else_sub_scope = &else_scope.base; |
| 1899 | 1940 | break :blk null; |
| 1900 | 1941 | }; |
| ... | ... | @@ -1981,7 +2022,7 @@ fn whileExpr( |
| 1981 | 2022 | const tree = scope.tree(); |
| 1982 | 2023 | const node_datas = tree.nodes.items(.data); |
| 1983 | 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 | 2026 | const void_type = try addZIRInstConst(mod, scope, while_src, .{ |
| 1986 | 2027 | .ty = Type.initTag(.type), |
| 1987 | 2028 | .val = Value.initTag(.void_type), |
| ... | ... | @@ -2028,7 +2069,7 @@ fn whileExpr( |
| 2028 | 2069 | }); |
| 2029 | 2070 | } |
| 2030 | 2071 | |
| 2031 | | const then_src = tree.token_locs[while_node.body.lastToken()].start; |
| 2072 | const then_src = token_starts[while_node.body.lastToken()]; |
| 2032 | 2073 | var then_scope: Scope.GenZIR = .{ |
| 2033 | 2074 | .parent = &continue_scope.base, |
| 2034 | 2075 | .decl = continue_scope.decl, |
| ... | ... | @@ -2055,19 +2096,19 @@ fn whileExpr( |
| 2055 | 2096 | |
| 2056 | 2097 | var else_src: usize = undefined; |
| 2057 | 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 | 2100 | // declare payload to the then_scope |
| 2060 | 2101 | const else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload); |
| 2061 | 2102 | |
| 2062 | 2103 | loop_scope.break_count += 1; |
| 2063 | 2104 | break :blk try expr(mod, else_sub_scope, loop_scope.break_result_loc, else_node.body); |
| 2064 | 2105 | } else blk: { |
| 2065 | | else_src = tree.token_locs[while_node.lastToken()].start; |
| 2106 | else_src = token_starts[while_node.lastToken()]; |
| 2066 | 2107 | break :blk null; |
| 2067 | 2108 | }; |
| 2068 | 2109 | if (loop_scope.label) |some| { |
| 2069 | 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 | 2114 | return finishThenElseBlock( |
| ... | ... | @@ -2105,7 +2146,7 @@ fn forExpr( |
| 2105 | 2146 | const tree = scope.tree(); |
| 2106 | 2147 | const node_datas = tree.nodes.items(.data); |
| 2107 | 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 | 2150 | const index_ptr = blk: { |
| 2110 | 2151 | const usize_type = try addZIRInstConst(mod, scope, for_src, .{ |
| 2111 | 2152 | .ty = Type.initTag(.type), |
| ... | ... | @@ -2121,7 +2162,7 @@ fn forExpr( |
| 2121 | 2162 | break :blk index_ptr; |
| 2122 | 2163 | }; |
| 2123 | 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 | 2166 | const len = try addZIRUnOp(mod, scope, cond_src, .indexable_ptr_len, array_ptr); |
| 2126 | 2167 | |
| 2127 | 2168 | var loop_scope: Scope.GenZIR = .{ |
| ... | ... | @@ -2191,7 +2232,7 @@ fn forExpr( |
| 2191 | 2232 | } |
| 2192 | 2233 | |
| 2193 | 2234 | // 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 | 2236 | var then_scope: Scope.GenZIR = .{ |
| 2196 | 2237 | .parent = &cond_scope.base, |
| 2197 | 2238 | .decl = cond_scope.decl, |
| ... | ... | @@ -2215,7 +2256,7 @@ fn forExpr( |
| 2215 | 2256 | const index_symbol_node = payload.index_symbol orelse |
| 2216 | 2257 | break :blk &then_scope.base; |
| 2217 | 2258 | |
| 2218 | | const index_name = tree.tokenSlice(index_symbol_node.firstToken()); |
| 2259 | const index_name = tree.tokenSlice(tree.firstToken(index_symbol_node)); |
| 2219 | 2260 | if (mem.eql(u8, index_name, "_")) { |
| 2220 | 2261 | break :blk &then_scope.base; |
| 2221 | 2262 | } |
| ... | ... | @@ -2244,16 +2285,16 @@ fn forExpr( |
| 2244 | 2285 | |
| 2245 | 2286 | var else_src: usize = undefined; |
| 2246 | 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 | 2289 | loop_scope.break_count += 1; |
| 2249 | 2290 | break :blk try expr(mod, &else_scope.base, loop_scope.break_result_loc, else_node.body); |
| 2250 | 2291 | } else blk: { |
| 2251 | | else_src = tree.token_locs[for_node.lastToken()].start; |
| 2292 | else_src = token_starts[for_node.lastToken()]; |
| 2252 | 2293 | break :blk null; |
| 2253 | 2294 | }; |
| 2254 | 2295 | if (loop_scope.label) |some| { |
| 2255 | 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 | 2300 | return finishThenElseBlock( |
| ... | ... | @@ -2299,7 +2340,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node |
| 2299 | 2340 | const tree = scope.tree(); |
| 2300 | 2341 | const node_datas = tree.nodes.items(.data); |
| 2301 | 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 | 2344 | const use_ref = switchCaseUsesRef(switch_node); |
| 2304 | 2345 | |
| 2305 | 2346 | var block_scope: Scope.GenZIR = .{ |
| ... | ... | @@ -2322,7 +2363,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node |
| 2322 | 2363 | var simple_case_count: usize = 0; |
| 2323 | 2364 | for (switch_node.cases()) |uncasted_case| { |
| 2324 | 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 | 2367 | assert(case.items_len != 0); |
| 2327 | 2368 | |
| 2328 | 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 | 2430 | if (getRangeNode(item)) |range| { |
| 2390 | 2431 | const start = try comptimeExpr(mod, &block_scope.base, .none, range.lhs); |
| 2391 | 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 | 2434 | const range_inst = try addZIRBinOp(mod, &block_scope.base, range_src, .switch_range, start, end); |
| 2394 | 2435 | try items.append(range_inst); |
| 2395 | 2436 | } else { |
| ... | ... | @@ -2447,7 +2488,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node |
| 2447 | 2488 | var case_index: usize = 0; |
| 2448 | 2489 | for (switch_node.cases()) |uncasted_case| { |
| 2449 | 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 | 2492 | // reset without freeing to reduce allocations. |
| 2452 | 2493 | case_scope.instructions.items.len = 0; |
| 2453 | 2494 | |
| ... | ... | @@ -2485,7 +2526,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node |
| 2485 | 2526 | var any_ok: ?*zir.Inst = null; |
| 2486 | 2527 | for (case.items()) |item| { |
| 2487 | 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 | 2530 | const range_inst = items.items[items_index].castTag(.switch_range).?; |
| 2490 | 2531 | items_index += 1; |
| 2491 | 2532 | |
| ... | ... | @@ -2565,7 +2606,7 @@ fn switchCaseExpr( |
| 2565 | 2606 | const tree = scope.tree(); |
| 2566 | 2607 | const node_datas = tree.nodes.items(.data); |
| 2567 | 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 | 2610 | const sub_scope = blk: { |
| 2570 | 2611 | const uncasted_payload = case.payload orelse break :blk scope; |
| 2571 | 2612 | const payload = uncasted_payload.castTag(.PointerPayload).?; |
| ... | ... | @@ -2593,7 +2634,7 @@ fn ret(mod: *Module, scope: *Scope, cfe: *ast.Node.ControlFlowExpression) InnerE |
| 2593 | 2634 | const tree = scope.tree(); |
| 2594 | 2635 | const node_datas = tree.nodes.items(.data); |
| 2595 | 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 | 2638 | if (cfe.getRHS()) |rhs_node| { |
| 2598 | 2639 | if (nodeMayNeedMemoryLocation(rhs_node, scope)) { |
| 2599 | 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 | 2650 | } |
| 2610 | 2651 | } |
| 2611 | 2652 | |
| 2612 | | fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneToken) InnerError!*zir.Inst { |
| 2653 | fn identifier( |
| 2654 | mod: *Module, |
| 2655 | scope: *Scope, |
| 2656 | rl: ResultLoc, |
| 2657 | ident: ast.Node.Index, |
| 2658 | ) InnerError!*zir.Inst { |
| 2613 | 2659 | const tracy = trace(@src()); |
| 2614 | 2660 | defer tracy.end(); |
| 2615 | 2661 | |
| 2616 | 2662 | const tree = scope.tree(); |
| 2617 | 2663 | const node_datas = tree.nodes.items(.data); |
| 2618 | 2664 | 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]; |
| 2621 | 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 | } |
| 2624 | 2672 | |
| 2625 | 2673 | if (getSimplePrimitiveValue(ident_name)) |typed_value| { |
| ... | ... | @@ -2634,7 +2682,7 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo |
| 2634 | 2682 | const bit_count = std.fmt.parseInt(u16, ident_name[1..], 10) catch |err| switch (err) { |
| 2635 | 2683 | error.Overflow => return mod.failNode( |
| 2636 | 2684 | scope, |
| 2637 | | &ident.base, |
| 2685 | ident, |
| 2638 | 2686 | "primitive integer type '{s}' exceeds maximum bit width of 65535", |
| 2639 | 2687 | .{ident_name}, |
| 2640 | 2688 | ), |
| ... | ... | @@ -2698,64 +2746,91 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo |
| 2698 | 2746 | } |
| 2699 | 2747 | } |
| 2700 | 2748 | |
| 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 | } |
| 2703 | 2751 | |
| 2704 | | fn stringLiteral(mod: *Module, scope: *Scope, str_lit: *ast.Node.OneToken) InnerError!*zir.Inst { |
| 2752 | fn stringLiteral( |
| 2753 | mod: *Module, |
| 2754 | scope: *Scope, |
| 2755 | rl: ResultLoc, |
| 2756 | str_lit: ast.Node.Index, |
| 2757 | ) InnerError!*zir.Inst { |
| 2705 | 2758 | const tree = scope.tree(); |
| 2706 | 2759 | const node_datas = tree.nodes.items(.data); |
| 2707 | 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 | 2764 | const arena = scope.arena(); |
| 2710 | 2765 | |
| 2711 | 2766 | var bad_index: usize = undefined; |
| 2712 | 2767 | const bytes = std.zig.parseStringLiteral(arena, unparsed_bytes, &bad_index) catch |err| switch (err) { |
| 2713 | 2768 | error.InvalidCharacter => { |
| 2714 | 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 | 2771 | return mod.fail(scope, src + bad_index, "invalid string literal character: '{c}'\n", .{bad_byte}); |
| 2717 | 2772 | }, |
| 2718 | 2773 | else => |e| return e, |
| 2719 | 2774 | }; |
| 2720 | 2775 | |
| 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); |
| 2723 | 2779 | } |
| 2724 | 2780 | |
| 2725 | | fn multilineStrLiteral(mod: *Module, scope: *Scope, node: *ast.Node.MultilineStringLiteral) !*zir.Inst { |
| 2781 | fn multilineStringLiteral( |
| 2782 | mod: *Module, |
| 2783 | scope: *Scope, |
| 2784 | rl: ResultLoc, |
| 2785 | str_lit: ast.Node.Index, |
| 2786 | ) InnerError!*zir.Inst { |
| 2726 | 2787 | const tree = scope.tree(); |
| 2727 | 2788 | const node_datas = tree.nodes.items(.data); |
| 2728 | 2789 | const main_tokens = tree.nodes.items(.main_token); |
| 2729 | | const lines = node.linesConst(); |
| 2730 | | const src = tree.token_locs[lines[0]].start; |
| 2731 | 2790 | |
| 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; |
| 2738 | 2793 | |
| 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; |
| 2745 | 2801 | } |
| 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); |
| 2752 | 2827 | } |
| 2753 | 2828 | |
| 2754 | 2829 | fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst { |
| 2755 | 2830 | const tree = scope.tree(); |
| 2756 | 2831 | const node_datas = tree.nodes.items(.data); |
| 2757 | 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 | 2834 | const slice = tree.tokenSlice(node.token); |
| 2760 | 2835 | |
| 2761 | 2836 | var bad_index: usize = undefined; |
| ... | ... | @@ -2772,13 +2847,19 @@ fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst |
| 2772 | 2847 | }); |
| 2773 | 2848 | } |
| 2774 | 2849 | |
| 2775 | | fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) InnerError!*zir.Inst { |
| 2850 | fn integerLiteral( |
| 2851 | mod: *Module, |
| 2852 | scope: *Scope, |
| 2853 | rl: ResultLoc, |
| 2854 | int_lit: ast.Node.Index, |
| 2855 | ) InnerError!*zir.Inst { |
| 2776 | 2856 | const arena = scope.arena(); |
| 2777 | 2857 | const tree = scope.tree(); |
| 2778 | | const node_datas = tree.nodes.items(.data); |
| 2779 | 2858 | 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")) |
| 2782 | 2863 | 16 |
| 2783 | 2864 | else if (mem.startsWith(u8, prefixed_bytes, "0o")) |
| 2784 | 2865 | 8 |
| ... | ... | @@ -2793,13 +2874,14 @@ fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) Inne |
| 2793 | 2874 | prefixed_bytes[2..]; |
| 2794 | 2875 | |
| 2795 | 2876 | 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, .{ |
| 2798 | 2879 | .ty = Type.initTag(.comptime_int), |
| 2799 | 2880 | .val = try Value.Tag.int_u64.create(arena, small_int), |
| 2800 | 2881 | }); |
| 2882 | return rvalue(mod, scope, rl, result); |
| 2801 | 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 | } |
| 2805 | 2887 | |
| ... | ... | @@ -2816,7 +2898,7 @@ fn floatLiteral(mod: *Module, scope: *Scope, float_lit: *ast.Node.OneToken) Inne |
| 2816 | 2898 | const float_number = std.fmt.parseFloat(f128, bytes) catch |e| switch (e) { |
| 2817 | 2899 | 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 | 2902 | return addZIRInstConst(mod, scope, src, .{ |
| 2821 | 2903 | .ty = Type.initTag(.comptime_float), |
| 2822 | 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 | 2910 | const tree = scope.tree(); |
| 2829 | 2911 | const node_datas = tree.nodes.items(.data); |
| 2830 | 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 | 2914 | return addZIRInstConst(mod, scope, src, .{ |
| 2833 | 2915 | .ty = Type.initTag(.@"undefined"), |
| 2834 | 2916 | .val = Value.initTag(.undef), |
| ... | ... | @@ -2840,7 +2922,7 @@ fn boolLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError |
| 2840 | 2922 | const tree = scope.tree(); |
| 2841 | 2923 | const node_datas = tree.nodes.items(.data); |
| 2842 | 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 | 2926 | return addZIRInstConst(mod, scope, src, .{ |
| 2845 | 2927 | .ty = Type.initTag(.bool), |
| 2846 | 2928 | .val = switch (tree.token_ids[node.token]) { |
| ... | ... | @@ -2856,34 +2938,34 @@ fn nullLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError |
| 2856 | 2938 | const tree = scope.tree(); |
| 2857 | 2939 | const node_datas = tree.nodes.items(.data); |
| 2858 | 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 | 2942 | return addZIRInstConst(mod, scope, src, .{ |
| 2861 | 2943 | .ty = Type.initTag(.@"null"), |
| 2862 | 2944 | .val = Value.initTag(.null_value), |
| 2863 | 2945 | }); |
| 2864 | 2946 | } |
| 2865 | 2947 | |
| 2866 | | fn 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 | | } |
| 2948 | fn assembly(mod: *Module, scope: *Scope, rl: ResultLoc, full: ast.full.Asm) InnerError!*zir.Inst { |
| 2870 | 2949 | const arena = scope.arena(); |
| 2871 | 2950 | const tree = scope.tree(); |
| 2872 | 2951 | const node_datas = tree.nodes.items(.data); |
| 2873 | 2952 | const main_tokens = tree.nodes.items(.main_token); |
| 2874 | 2953 | |
| 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 | } |
| 2877 | 2957 | |
| 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); |
| 2879 | 2960 | |
| 2961 | const src = token_starts[full.ast.asm_token]; |
| 2880 | 2962 | const str_type = try addZIRInstConst(mod, scope, src, .{ |
| 2881 | 2963 | .ty = Type.initTag(.type), |
| 2882 | 2964 | .val = Value.initTag(.const_slice_u8_type), |
| 2883 | 2965 | }); |
| 2884 | 2966 | const str_type_rl: ResultLoc = .{ .ty = str_type }; |
| 2885 | 2967 | |
| 2886 | | for (asm_node.inputs) |input, i| { |
| 2968 | for (full.inputs) |input, i| { |
| 2887 | 2969 | // TODO semantically analyze constraints |
| 2888 | 2970 | inputs[i] = try expr(mod, scope, str_type_rl, input.constraint); |
| 2889 | 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 | 2976 | .val = Value.initTag(.void_type), |
| 2895 | 2977 | }); |
| 2896 | 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 | 2980 | .return_type = return_type, |
| 2899 | 2981 | }, .{ |
| 2900 | | .@"volatile" = asm_node.volatile_token != null, |
| 2982 | .@"volatile" = full.volatile_token != null, |
| 2901 | 2983 | //.clobbers = TODO handle clobbers |
| 2902 | 2984 | .inputs = inputs, |
| 2903 | 2985 | .args = args, |
| 2904 | 2986 | }); |
| 2905 | | return asm_inst; |
| 2987 | return rvalue(mod, scope, rl, asm_inst); |
| 2906 | 2988 | } |
| 2907 | 2989 | |
| 2908 | 2990 | fn ensureBuiltinParamCount(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call, count: u32) !void { |
| ... | ... | @@ -2924,7 +3006,7 @@ fn simpleCast( |
| 2924 | 3006 | const tree = scope.tree(); |
| 2925 | 3007 | const node_datas = tree.nodes.items(.data); |
| 2926 | 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 | 3010 | const params = call.params(); |
| 2929 | 3011 | const dest_type = try typeExpr(mod, scope, params[0]); |
| 2930 | 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 | 3020 | const tree = scope.tree(); |
| 2939 | 3021 | const node_datas = tree.nodes.items(.data); |
| 2940 | 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 | 3024 | return addZIRUnOp(mod, scope, src, .ptrtoint, operand); |
| 2943 | 3025 | } |
| 2944 | 3026 | |
| ... | ... | @@ -2952,7 +3034,7 @@ fn as( |
| 2952 | 3034 | const tree = scope.tree(); |
| 2953 | 3035 | const node_datas = tree.nodes.items(.data); |
| 2954 | 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 | 3038 | const params = call.params(); |
| 2957 | 3039 | const dest_type = try typeExpr(mod, scope, params[0]); |
| 2958 | 3040 | switch (rl) { |
| ... | ... | @@ -3028,7 +3110,7 @@ fn bitCast(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.builtin_c |
| 3028 | 3110 | const tree = scope.tree(); |
| 3029 | 3111 | const node_datas = tree.nodes.items(.data); |
| 3030 | 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 | 3114 | const params = call.params(); |
| 3033 | 3115 | const dest_type = try typeExpr(mod, scope, params[0]); |
| 3034 | 3116 | switch (rl) { |
| ... | ... | @@ -3074,7 +3156,7 @@ fn import(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerError! |
| 3074 | 3156 | const tree = scope.tree(); |
| 3075 | 3157 | const node_datas = tree.nodes.items(.data); |
| 3076 | 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 | 3160 | const params = call.params(); |
| 3079 | 3161 | const target = try expr(mod, scope, .none, params[0]); |
| 3080 | 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 | 3167 | const tree = scope.tree(); |
| 3086 | 3168 | const node_datas = tree.nodes.items(.data); |
| 3087 | 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 | 3171 | const params = call.params(); |
| 3090 | 3172 | const target = try expr(mod, scope, .none, params[0]); |
| 3091 | 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 | 3178 | const tree = scope.tree(); |
| 3097 | 3179 | const node_datas = tree.nodes.items(.data); |
| 3098 | 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 | 3182 | const params = call.params(); |
| 3101 | 3183 | const u32_type = try addZIRInstConst(mod, scope, src, .{ |
| 3102 | 3184 | .ty = Type.initTag(.type), |
| ... | ... | @@ -3111,7 +3193,7 @@ fn typeOf(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.builtin_ca |
| 3111 | 3193 | const node_datas = tree.nodes.items(.data); |
| 3112 | 3194 | const main_tokens = tree.nodes.items(.main_token); |
| 3113 | 3195 | const arena = scope.arena(); |
| 3114 | | const src = tree.token_locs[call.builtin_token].start; |
| 3196 | const src = token_starts[call.builtin_token]; |
| 3115 | 3197 | const params = call.params(); |
| 3116 | 3198 | if (params.len < 1) { |
| 3117 | 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 | 3211 | const node_datas = tree.nodes.items(.data); |
| 3130 | 3212 | const main_tokens = tree.nodes.items(.main_token); |
| 3131 | 3213 | const arena = scope.arena(); |
| 3132 | | const src = tree.token_locs[call.builtin_token].start; |
| 3214 | const src = token_starts[call.builtin_token]; |
| 3133 | 3215 | const params = call.params(); |
| 3134 | 3216 | var targets = try arena.alloc(*zir.Inst, params.len); |
| 3135 | 3217 | for (params) |param, param_i| |
| ... | ... | @@ -3161,7 +3243,7 @@ fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.built |
| 3161 | 3243 | } else if (mem.eql(u8, builtin_name, "@TypeOf")) { |
| 3162 | 3244 | return typeOf(mod, scope, rl, call); |
| 3163 | 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 | 3247 | return rvalue(mod, scope, rl, try addZIRNoOp(mod, scope, src, .breakpoint)); |
| 3166 | 3248 | } else if (mem.eql(u8, builtin_name, "@import")) { |
| 3167 | 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 | 3269 | const param_nodes = node.params(); |
| 3188 | 3270 | const args = try scope.getGenZIR().arena.alloc(*zir.Inst, param_nodes.len); |
| 3189 | 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 | 3273 | const param_type = try addZIRInst(mod, scope, param_src, zir.Inst.ParamType, .{ |
| 3192 | 3274 | .func = lhs, |
| 3193 | 3275 | .arg_index = i, |
| ... | ... | @@ -3195,7 +3277,7 @@ fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.call) In |
| 3195 | 3277 | args[i] = try expr(mod, scope, .{ .ty = param_type }, param_node); |
| 3196 | 3278 | } |
| 3197 | 3279 | |
| 3198 | | const src = tree.token_locs[node.lhs.firstToken()].start; |
| 3280 | const src = token_starts[node.lhs.firstToken()]; |
| 3199 | 3281 | const result = try addZIRInst(mod, scope, src, zir.Inst.Call, .{ |
| 3200 | 3282 | .func = lhs, |
| 3201 | 3283 | .args = args, |
| ... | ... | @@ -3208,7 +3290,7 @@ fn unreach(mod: *Module, scope: *Scope, unreach_node: *ast.Node.OneToken) InnerE |
| 3208 | 3290 | const tree = scope.tree(); |
| 3209 | 3291 | const node_datas = tree.nodes.items(.data); |
| 3210 | 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 | 3294 | return addZIRNoOp(mod, scope, src, .unreachable_safe); |
| 3213 | 3295 | } |
| 3214 | 3296 | |
| ... | ... | @@ -3528,6 +3610,8 @@ fn rvalue(mod: *Module, scope: *Scope, rl: ResultLoc, result: *zir.Inst) InnerEr |
| 3528 | 3610 | } |
| 3529 | 3611 | } |
| 3530 | 3612 | |
| 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. |
| 3531 | 3615 | fn rvalueVoid( |
| 3532 | 3616 | mod: *Module, |
| 3533 | 3617 | scope: *Scope, |