| ... | ... | @@ -37,6 +37,8 @@ string_table: std.StringHashMapUnmanaged(u32) = .{}, |
| 37 | 37 | compile_errors: ArrayListUnmanaged(Zir.Inst.CompileErrors.Item) = .{}, |
| 38 | 38 | /// String table indexes, keeps track of all `@import` operands. |
| 39 | 39 | imports: std.AutoArrayHashMapUnmanaged(u32, void) = .{}, |
| 40 | /// The topmost block of the current function. |
| 41 | fn_block: ?*GenZir = null, |
| 40 | 42 | |
| 41 | 43 | pub fn addExtra(astgen: *AstGen, extra: anytype) Allocator.Error!u32 { |
| 42 | 44 | const fields = std.meta.fields(@TypeOf(extra)); |
| ... | ... | @@ -82,7 +84,7 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir { |
| 82 | 84 | // First few indexes of extra are reserved and set at the end. |
| 83 | 85 | try astgen.extra.resize(gpa, @typeInfo(Zir.ExtraIndex).Enum.fields.len); |
| 84 | 86 | |
| 85 | | var gen_scope: Scope.GenZir = .{ |
| 87 | var gen_scope: GenZir = .{ |
| 86 | 88 | .force_comptime = true, |
| 87 | 89 | .parent = &file.base, |
| 88 | 90 | .decl_node_index = 0, |
| ... | ... | @@ -461,6 +463,8 @@ pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inn |
| 461 | 463 | .local_var_decl => unreachable, // Handled in `blockExpr`. |
| 462 | 464 | .simple_var_decl => unreachable, // Handled in `blockExpr`. |
| 463 | 465 | .aligned_var_decl => unreachable, // Handled in `blockExpr`. |
| 466 | .@"defer" => unreachable, // Handled in `blockExpr`. |
| 467 | .@"errdefer" => unreachable, // Handled in `blockExpr`. |
| 464 | 468 | |
| 465 | 469 | .switch_case => unreachable, // Handled in `switchExpr`. |
| 466 | 470 | .switch_case_one => unreachable, // Handled in `switchExpr`. |
| ... | ... | @@ -818,8 +822,6 @@ pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inn |
| 818 | 822 | .@"await" => return astgen.failNode(node, "async and related features are not yet supported", .{}), |
| 819 | 823 | .@"resume" => return astgen.failNode(node, "async and related features are not yet supported", .{}), |
| 820 | 824 | |
| 821 | | .@"defer" => return astgen.failNode(node, "TODO implement astgen.expr for .defer", .{}), |
| 822 | | .@"errdefer" => return astgen.failNode(node, "TODO implement astgen.expr for .errdefer", .{}), |
| 823 | 825 | .@"try" => return tryExpr(gz, scope, rl, node_datas[node].lhs), |
| 824 | 826 | |
| 825 | 827 | .array_init_one, .array_init_one_comma => { |
| ... | ... | @@ -1245,6 +1247,8 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn |
| 1245 | 1247 | }, |
| 1246 | 1248 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 1247 | 1249 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| 1250 | .defer_normal => @panic("TODO break/defer"), |
| 1251 | .defer_error => @panic("TODO break/defer"), |
| 1248 | 1252 | else => if (break_label != 0) { |
| 1249 | 1253 | const label_name = try astgen.identifierTokenString(break_label); |
| 1250 | 1254 | return astgen.failTok(break_label, "label not found: '{s}'", .{label_name}); |
| ... | ... | @@ -1290,6 +1294,8 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) |
| 1290 | 1294 | }, |
| 1291 | 1295 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 1292 | 1296 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| 1297 | .defer_normal => @panic("TODO continue/defer"), |
| 1298 | .defer_error => @panic("TODO continue/defer"), |
| 1293 | 1299 | else => if (break_label != 0) { |
| 1294 | 1300 | const label_name = try astgen.identifierTokenString(break_label); |
| 1295 | 1301 | return astgen.failTok(break_label, "label not found: '{s}'", .{label_name}); |
| ... | ... | @@ -1354,6 +1360,7 @@ fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: ast.Toke |
| 1354 | 1360 | }, |
| 1355 | 1361 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 1356 | 1362 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| 1363 | .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent, |
| 1357 | 1364 | else => return, |
| 1358 | 1365 | } |
| 1359 | 1366 | } |
| ... | ... | @@ -1393,6 +1400,7 @@ fn labeledBlockExpr( |
| 1393 | 1400 | .decl_node_index = gz.decl_node_index, |
| 1394 | 1401 | .astgen = gz.astgen, |
| 1395 | 1402 | .force_comptime = gz.force_comptime, |
| 1403 | .ref_start_index = gz.ref_start_index, |
| 1396 | 1404 | .instructions = .{}, |
| 1397 | 1405 | // TODO @as here is working around a stage1 miscompilation bug :( |
| 1398 | 1406 | .label = @as(?GenZir.Label, GenZir.Label{ |
| ... | ... | @@ -1463,16 +1471,16 @@ fn blockExprStmts( |
| 1463 | 1471 | |
| 1464 | 1472 | var scope = parent_scope; |
| 1465 | 1473 | for (statements) |statement| { |
| 1466 | | if (!gz.force_comptime) { |
| 1467 | | _ = try gz.addNode(.dbg_stmt_node, statement); |
| 1468 | | } |
| 1469 | 1474 | switch (node_tags[statement]) { |
| 1470 | | .global_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.globalVarDecl(statement)), |
| 1471 | | .local_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.localVarDecl(statement)), |
| 1472 | | .simple_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.simpleVarDecl(statement)), |
| 1475 | // zig fmt: off |
| 1476 | .global_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.globalVarDecl(statement)), |
| 1477 | .local_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.localVarDecl(statement)), |
| 1478 | .simple_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.simpleVarDecl(statement)), |
| 1473 | 1479 | .aligned_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.alignedVarDecl(statement)), |
| 1474 | 1480 | |
| 1475 | | // zig fmt: off |
| 1481 | .@"defer" => scope = try deferStmt(gz, scope, statement, &block_arena.allocator, .defer_normal), |
| 1482 | .@"errdefer" => scope = try deferStmt(gz, scope, statement, &block_arena.allocator, .defer_error), |
| 1483 | |
| 1476 | 1484 | .assign => try assign(gz, scope, statement), |
| 1477 | 1485 | |
| 1478 | 1486 | .assign_bit_shift_left => try assignShift(gz, scope, statement, .shl), |
| ... | ... | @@ -1489,302 +1497,357 @@ fn blockExprStmts( |
| 1489 | 1497 | .assign_add_wrap => try assignOp(gz, scope, statement, .addwrap), |
| 1490 | 1498 | .assign_mul => try assignOp(gz, scope, statement, .mul), |
| 1491 | 1499 | .assign_mul_wrap => try assignOp(gz, scope, statement, .mulwrap), |
| 1500 | |
| 1501 | else => try unusedResultExpr(gz, scope, statement), |
| 1492 | 1502 | // zig fmt: on |
| 1503 | } |
| 1504 | } |
| 1493 | 1505 | |
| 1494 | | else => { |
| 1495 | | // We need to emit an error if the result is not `noreturn` or `void`, but |
| 1496 | | // we want to avoid adding the ZIR instruction if possible for performance. |
| 1497 | | const maybe_unused_result = try expr(gz, scope, .none, statement); |
| 1498 | | const elide_check = if (gz.refToIndex(maybe_unused_result)) |inst| b: { |
| 1499 | | // Note that this array becomes invalid after appending more items to it |
| 1500 | | // in the above while loop. |
| 1501 | | const zir_tags = gz.astgen.instructions.items(.tag); |
| 1502 | | switch (zir_tags[inst]) { |
| 1503 | | // For some instructions, swap in a slightly different ZIR tag |
| 1504 | | // so we can avoid a separate ensure_result_used instruction. |
| 1505 | | .call_none_chkused => unreachable, |
| 1506 | | .call_none => { |
| 1507 | | zir_tags[inst] = .call_none_chkused; |
| 1508 | | break :b true; |
| 1509 | | }, |
| 1510 | | .call_chkused => unreachable, |
| 1511 | | .call => { |
| 1512 | | zir_tags[inst] = .call_chkused; |
| 1513 | | break :b true; |
| 1514 | | }, |
| 1506 | try genDefers(gz, parent_scope, scope, .none); |
| 1507 | } |
| 1515 | 1508 | |
| 1516 | | // ZIR instructions that might be a type other than `noreturn` or `void`. |
| 1517 | | .add, |
| 1518 | | .addwrap, |
| 1519 | | .alloc, |
| 1520 | | .alloc_mut, |
| 1521 | | .alloc_inferred, |
| 1522 | | .alloc_inferred_mut, |
| 1523 | | .array_cat, |
| 1524 | | .array_mul, |
| 1525 | | .array_type, |
| 1526 | | .array_type_sentinel, |
| 1527 | | .elem_type, |
| 1528 | | .indexable_ptr_len, |
| 1529 | | .as, |
| 1530 | | .as_node, |
| 1531 | | .@"asm", |
| 1532 | | .asm_volatile, |
| 1533 | | .bit_and, |
| 1534 | | .bitcast, |
| 1535 | | .bitcast_result_ptr, |
| 1536 | | .bit_or, |
| 1537 | | .block, |
| 1538 | | .block_inline, |
| 1539 | | .block_inline_var, |
| 1540 | | .loop, |
| 1541 | | .bool_br_and, |
| 1542 | | .bool_br_or, |
| 1543 | | .bool_not, |
| 1544 | | .bool_and, |
| 1545 | | .bool_or, |
| 1546 | | .call_compile_time, |
| 1547 | | .cmp_lt, |
| 1548 | | .cmp_lte, |
| 1549 | | .cmp_eq, |
| 1550 | | .cmp_gte, |
| 1551 | | .cmp_gt, |
| 1552 | | .cmp_neq, |
| 1553 | | .coerce_result_ptr, |
| 1554 | | .decl_ref, |
| 1555 | | .decl_val, |
| 1556 | | .load, |
| 1557 | | .div, |
| 1558 | | .elem_ptr, |
| 1559 | | .elem_val, |
| 1560 | | .elem_ptr_node, |
| 1561 | | .elem_val_node, |
| 1562 | | .field_ptr, |
| 1563 | | .field_val, |
| 1564 | | .field_ptr_named, |
| 1565 | | .field_val_named, |
| 1566 | | .func, |
| 1567 | | .func_inferred, |
| 1568 | | .int, |
| 1569 | | .float, |
| 1570 | | .float128, |
| 1571 | | .intcast, |
| 1572 | | .int_type, |
| 1573 | | .is_non_null, |
| 1574 | | .is_null, |
| 1575 | | .is_non_null_ptr, |
| 1576 | | .is_null_ptr, |
| 1577 | | .is_err, |
| 1578 | | .is_err_ptr, |
| 1579 | | .mod_rem, |
| 1580 | | .mul, |
| 1581 | | .mulwrap, |
| 1582 | | .param_type, |
| 1583 | | .ptrtoint, |
| 1584 | | .ref, |
| 1585 | | .shl, |
| 1586 | | .shr, |
| 1587 | | .str, |
| 1588 | | .sub, |
| 1589 | | .subwrap, |
| 1590 | | .negate, |
| 1591 | | .negate_wrap, |
| 1592 | | .typeof, |
| 1593 | | .typeof_elem, |
| 1594 | | .xor, |
| 1595 | | .optional_type, |
| 1596 | | .optional_type_from_ptr_elem, |
| 1597 | | .optional_payload_safe, |
| 1598 | | .optional_payload_unsafe, |
| 1599 | | .optional_payload_safe_ptr, |
| 1600 | | .optional_payload_unsafe_ptr, |
| 1601 | | .err_union_payload_safe, |
| 1602 | | .err_union_payload_unsafe, |
| 1603 | | .err_union_payload_safe_ptr, |
| 1604 | | .err_union_payload_unsafe_ptr, |
| 1605 | | .err_union_code, |
| 1606 | | .err_union_code_ptr, |
| 1607 | | .ptr_type, |
| 1608 | | .ptr_type_simple, |
| 1609 | | .enum_literal, |
| 1610 | | .enum_literal_small, |
| 1611 | | .merge_error_sets, |
| 1612 | | .error_union_type, |
| 1613 | | .bit_not, |
| 1614 | | .error_value, |
| 1615 | | .error_to_int, |
| 1616 | | .int_to_error, |
| 1617 | | .slice_start, |
| 1618 | | .slice_end, |
| 1619 | | .slice_sentinel, |
| 1620 | | .import, |
| 1621 | | .typeof_peer, |
| 1622 | | .switch_block, |
| 1623 | | .switch_block_multi, |
| 1624 | | .switch_block_else, |
| 1625 | | .switch_block_else_multi, |
| 1626 | | .switch_block_under, |
| 1627 | | .switch_block_under_multi, |
| 1628 | | .switch_block_ref, |
| 1629 | | .switch_block_ref_multi, |
| 1630 | | .switch_block_ref_else, |
| 1631 | | .switch_block_ref_else_multi, |
| 1632 | | .switch_block_ref_under, |
| 1633 | | .switch_block_ref_under_multi, |
| 1634 | | .switch_capture, |
| 1635 | | .switch_capture_ref, |
| 1636 | | .switch_capture_multi, |
| 1637 | | .switch_capture_multi_ref, |
| 1638 | | .switch_capture_else, |
| 1639 | | .switch_capture_else_ref, |
| 1640 | | .struct_init_empty, |
| 1641 | | .struct_init, |
| 1642 | | .struct_init_anon, |
| 1643 | | .array_init, |
| 1644 | | .array_init_anon, |
| 1645 | | .array_init_ref, |
| 1646 | | .array_init_anon_ref, |
| 1647 | | .union_init_ptr, |
| 1648 | | .field_type, |
| 1649 | | .field_type_ref, |
| 1650 | | .struct_decl, |
| 1651 | | .struct_decl_packed, |
| 1652 | | .struct_decl_extern, |
| 1653 | | .union_decl, |
| 1654 | | .enum_decl, |
| 1655 | | .enum_decl_nonexhaustive, |
| 1656 | | .opaque_decl, |
| 1657 | | .error_set_decl, |
| 1658 | | .int_to_enum, |
| 1659 | | .enum_to_int, |
| 1660 | | .type_info, |
| 1661 | | .size_of, |
| 1662 | | .bit_size_of, |
| 1663 | | .add_with_overflow, |
| 1664 | | .sub_with_overflow, |
| 1665 | | .mul_with_overflow, |
| 1666 | | .shl_with_overflow, |
| 1667 | | .log2_int_type, |
| 1668 | | .typeof_log2_int_type, |
| 1669 | | .ptr_to_int, |
| 1670 | | .align_of, |
| 1671 | | .bool_to_int, |
| 1672 | | .embed_file, |
| 1673 | | .error_name, |
| 1674 | | .sqrt, |
| 1675 | | .sin, |
| 1676 | | .cos, |
| 1677 | | .exp, |
| 1678 | | .exp2, |
| 1679 | | .log, |
| 1680 | | .log2, |
| 1681 | | .log10, |
| 1682 | | .fabs, |
| 1683 | | .floor, |
| 1684 | | .ceil, |
| 1685 | | .trunc, |
| 1686 | | .round, |
| 1687 | | .tag_name, |
| 1688 | | .reify, |
| 1689 | | .type_name, |
| 1690 | | .frame_type, |
| 1691 | | .frame_size, |
| 1692 | | .float_to_int, |
| 1693 | | .int_to_float, |
| 1694 | | .int_to_ptr, |
| 1695 | | .float_cast, |
| 1696 | | .int_cast, |
| 1697 | | .err_set_cast, |
| 1698 | | .ptr_cast, |
| 1699 | | .truncate, |
| 1700 | | .align_cast, |
| 1701 | | .has_decl, |
| 1702 | | .has_field, |
| 1703 | | .clz, |
| 1704 | | .ctz, |
| 1705 | | .pop_count, |
| 1706 | | .byte_swap, |
| 1707 | | .bit_reverse, |
| 1708 | | .div_exact, |
| 1709 | | .div_floor, |
| 1710 | | .div_trunc, |
| 1711 | | .mod, |
| 1712 | | .rem, |
| 1713 | | .shl_exact, |
| 1714 | | .shr_exact, |
| 1715 | | .bit_offset_of, |
| 1716 | | .byte_offset_of, |
| 1717 | | .cmpxchg_strong, |
| 1718 | | .cmpxchg_weak, |
| 1719 | | .splat, |
| 1720 | | .reduce, |
| 1721 | | .shuffle, |
| 1722 | | .atomic_load, |
| 1723 | | .atomic_rmw, |
| 1724 | | .atomic_store, |
| 1725 | | .mul_add, |
| 1726 | | .builtin_call, |
| 1727 | | .field_ptr_type, |
| 1728 | | .field_parent_ptr, |
| 1729 | | .memcpy, |
| 1730 | | .memset, |
| 1731 | | .builtin_async_call, |
| 1732 | | .c_import, |
| 1733 | | .extended, |
| 1734 | | => break :b false, |
| 1735 | | |
| 1736 | | // ZIR instructions that are always either `noreturn` or `void`. |
| 1737 | | .breakpoint, |
| 1738 | | .fence, |
| 1739 | | .dbg_stmt_node, |
| 1740 | | .ensure_result_used, |
| 1741 | | .ensure_result_non_error, |
| 1742 | | .@"export", |
| 1743 | | .set_eval_branch_quota, |
| 1744 | | .compile_log, |
| 1745 | | .ensure_err_payload_void, |
| 1746 | | .@"break", |
| 1747 | | .break_inline, |
| 1748 | | .condbr, |
| 1749 | | .condbr_inline, |
| 1750 | | .compile_error, |
| 1751 | | .ret_node, |
| 1752 | | .ret_tok, |
| 1753 | | .ret_coerce, |
| 1754 | | .@"unreachable", |
| 1755 | | .store, |
| 1756 | | .store_node, |
| 1757 | | .store_to_block_ptr, |
| 1758 | | .store_to_inferred_ptr, |
| 1759 | | .resolve_inferred_alloc, |
| 1760 | | .repeat, |
| 1761 | | .repeat_inline, |
| 1762 | | .validate_struct_init_ptr, |
| 1763 | | .validate_array_init_ptr, |
| 1764 | | .panic, |
| 1765 | | .set_align_stack, |
| 1766 | | .set_cold, |
| 1767 | | .set_float_mode, |
| 1768 | | .set_runtime_safety, |
| 1769 | | => break :b true, |
| 1770 | | } |
| 1771 | | } else switch (maybe_unused_result) { |
| 1772 | | .none => unreachable, |
| 1509 | fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) InnerError!void { |
| 1510 | try emitDbgNode(gz, statement); |
| 1511 | // We need to emit an error if the result is not `noreturn` or `void`, but |
| 1512 | // we want to avoid adding the ZIR instruction if possible for performance. |
| 1513 | const maybe_unused_result = try expr(gz, scope, .none, statement); |
| 1514 | const elide_check = if (gz.refToIndex(maybe_unused_result)) |inst| b: { |
| 1515 | // Note that this array becomes invalid after appending more items to it |
| 1516 | // in the above while loop. |
| 1517 | const zir_tags = gz.astgen.instructions.items(.tag); |
| 1518 | switch (zir_tags[inst]) { |
| 1519 | // For some instructions, swap in a slightly different ZIR tag |
| 1520 | // so we can avoid a separate ensure_result_used instruction. |
| 1521 | .call_none_chkused => unreachable, |
| 1522 | .call_none => { |
| 1523 | zir_tags[inst] = .call_none_chkused; |
| 1524 | break :b true; |
| 1525 | }, |
| 1526 | .call_chkused => unreachable, |
| 1527 | .call => { |
| 1528 | zir_tags[inst] = .call_chkused; |
| 1529 | break :b true; |
| 1530 | }, |
| 1773 | 1531 | |
| 1774 | | .void_value, |
| 1775 | | .unreachable_value, |
| 1776 | | => true, |
| 1532 | // ZIR instructions that might be a type other than `noreturn` or `void`. |
| 1533 | .add, |
| 1534 | .addwrap, |
| 1535 | .alloc, |
| 1536 | .alloc_mut, |
| 1537 | .alloc_inferred, |
| 1538 | .alloc_inferred_mut, |
| 1539 | .array_cat, |
| 1540 | .array_mul, |
| 1541 | .array_type, |
| 1542 | .array_type_sentinel, |
| 1543 | .elem_type, |
| 1544 | .indexable_ptr_len, |
| 1545 | .as, |
| 1546 | .as_node, |
| 1547 | .@"asm", |
| 1548 | .asm_volatile, |
| 1549 | .bit_and, |
| 1550 | .bitcast, |
| 1551 | .bitcast_result_ptr, |
| 1552 | .bit_or, |
| 1553 | .block, |
| 1554 | .block_inline, |
| 1555 | .block_inline_var, |
| 1556 | .loop, |
| 1557 | .bool_br_and, |
| 1558 | .bool_br_or, |
| 1559 | .bool_not, |
| 1560 | .bool_and, |
| 1561 | .bool_or, |
| 1562 | .call_compile_time, |
| 1563 | .cmp_lt, |
| 1564 | .cmp_lte, |
| 1565 | .cmp_eq, |
| 1566 | .cmp_gte, |
| 1567 | .cmp_gt, |
| 1568 | .cmp_neq, |
| 1569 | .coerce_result_ptr, |
| 1570 | .decl_ref, |
| 1571 | .decl_val, |
| 1572 | .load, |
| 1573 | .div, |
| 1574 | .elem_ptr, |
| 1575 | .elem_val, |
| 1576 | .elem_ptr_node, |
| 1577 | .elem_val_node, |
| 1578 | .field_ptr, |
| 1579 | .field_val, |
| 1580 | .field_ptr_named, |
| 1581 | .field_val_named, |
| 1582 | .func, |
| 1583 | .func_inferred, |
| 1584 | .int, |
| 1585 | .float, |
| 1586 | .float128, |
| 1587 | .intcast, |
| 1588 | .int_type, |
| 1589 | .is_non_null, |
| 1590 | .is_null, |
| 1591 | .is_non_null_ptr, |
| 1592 | .is_null_ptr, |
| 1593 | .is_err, |
| 1594 | .is_err_ptr, |
| 1595 | .mod_rem, |
| 1596 | .mul, |
| 1597 | .mulwrap, |
| 1598 | .param_type, |
| 1599 | .ptrtoint, |
| 1600 | .ref, |
| 1601 | .shl, |
| 1602 | .shr, |
| 1603 | .str, |
| 1604 | .sub, |
| 1605 | .subwrap, |
| 1606 | .negate, |
| 1607 | .negate_wrap, |
| 1608 | .typeof, |
| 1609 | .typeof_elem, |
| 1610 | .xor, |
| 1611 | .optional_type, |
| 1612 | .optional_type_from_ptr_elem, |
| 1613 | .optional_payload_safe, |
| 1614 | .optional_payload_unsafe, |
| 1615 | .optional_payload_safe_ptr, |
| 1616 | .optional_payload_unsafe_ptr, |
| 1617 | .err_union_payload_safe, |
| 1618 | .err_union_payload_unsafe, |
| 1619 | .err_union_payload_safe_ptr, |
| 1620 | .err_union_payload_unsafe_ptr, |
| 1621 | .err_union_code, |
| 1622 | .err_union_code_ptr, |
| 1623 | .ptr_type, |
| 1624 | .ptr_type_simple, |
| 1625 | .enum_literal, |
| 1626 | .enum_literal_small, |
| 1627 | .merge_error_sets, |
| 1628 | .error_union_type, |
| 1629 | .bit_not, |
| 1630 | .error_value, |
| 1631 | .error_to_int, |
| 1632 | .int_to_error, |
| 1633 | .slice_start, |
| 1634 | .slice_end, |
| 1635 | .slice_sentinel, |
| 1636 | .import, |
| 1637 | .typeof_peer, |
| 1638 | .switch_block, |
| 1639 | .switch_block_multi, |
| 1640 | .switch_block_else, |
| 1641 | .switch_block_else_multi, |
| 1642 | .switch_block_under, |
| 1643 | .switch_block_under_multi, |
| 1644 | .switch_block_ref, |
| 1645 | .switch_block_ref_multi, |
| 1646 | .switch_block_ref_else, |
| 1647 | .switch_block_ref_else_multi, |
| 1648 | .switch_block_ref_under, |
| 1649 | .switch_block_ref_under_multi, |
| 1650 | .switch_capture, |
| 1651 | .switch_capture_ref, |
| 1652 | .switch_capture_multi, |
| 1653 | .switch_capture_multi_ref, |
| 1654 | .switch_capture_else, |
| 1655 | .switch_capture_else_ref, |
| 1656 | .struct_init_empty, |
| 1657 | .struct_init, |
| 1658 | .struct_init_anon, |
| 1659 | .array_init, |
| 1660 | .array_init_anon, |
| 1661 | .array_init_ref, |
| 1662 | .array_init_anon_ref, |
| 1663 | .union_init_ptr, |
| 1664 | .field_type, |
| 1665 | .field_type_ref, |
| 1666 | .struct_decl, |
| 1667 | .struct_decl_packed, |
| 1668 | .struct_decl_extern, |
| 1669 | .union_decl, |
| 1670 | .enum_decl, |
| 1671 | .enum_decl_nonexhaustive, |
| 1672 | .opaque_decl, |
| 1673 | .error_set_decl, |
| 1674 | .int_to_enum, |
| 1675 | .enum_to_int, |
| 1676 | .type_info, |
| 1677 | .size_of, |
| 1678 | .bit_size_of, |
| 1679 | .add_with_overflow, |
| 1680 | .sub_with_overflow, |
| 1681 | .mul_with_overflow, |
| 1682 | .shl_with_overflow, |
| 1683 | .log2_int_type, |
| 1684 | .typeof_log2_int_type, |
| 1685 | .ptr_to_int, |
| 1686 | .align_of, |
| 1687 | .bool_to_int, |
| 1688 | .embed_file, |
| 1689 | .error_name, |
| 1690 | .sqrt, |
| 1691 | .sin, |
| 1692 | .cos, |
| 1693 | .exp, |
| 1694 | .exp2, |
| 1695 | .log, |
| 1696 | .log2, |
| 1697 | .log10, |
| 1698 | .fabs, |
| 1699 | .floor, |
| 1700 | .ceil, |
| 1701 | .trunc, |
| 1702 | .round, |
| 1703 | .tag_name, |
| 1704 | .reify, |
| 1705 | .type_name, |
| 1706 | .frame_type, |
| 1707 | .frame_size, |
| 1708 | .float_to_int, |
| 1709 | .int_to_float, |
| 1710 | .int_to_ptr, |
| 1711 | .float_cast, |
| 1712 | .int_cast, |
| 1713 | .err_set_cast, |
| 1714 | .ptr_cast, |
| 1715 | .truncate, |
| 1716 | .align_cast, |
| 1717 | .has_decl, |
| 1718 | .has_field, |
| 1719 | .clz, |
| 1720 | .ctz, |
| 1721 | .pop_count, |
| 1722 | .byte_swap, |
| 1723 | .bit_reverse, |
| 1724 | .div_exact, |
| 1725 | .div_floor, |
| 1726 | .div_trunc, |
| 1727 | .mod, |
| 1728 | .rem, |
| 1729 | .shl_exact, |
| 1730 | .shr_exact, |
| 1731 | .bit_offset_of, |
| 1732 | .byte_offset_of, |
| 1733 | .cmpxchg_strong, |
| 1734 | .cmpxchg_weak, |
| 1735 | .splat, |
| 1736 | .reduce, |
| 1737 | .shuffle, |
| 1738 | .atomic_load, |
| 1739 | .atomic_rmw, |
| 1740 | .atomic_store, |
| 1741 | .mul_add, |
| 1742 | .builtin_call, |
| 1743 | .field_ptr_type, |
| 1744 | .field_parent_ptr, |
| 1745 | .memcpy, |
| 1746 | .memset, |
| 1747 | .builtin_async_call, |
| 1748 | .c_import, |
| 1749 | .extended, |
| 1750 | => break :b false, |
| 1751 | |
| 1752 | // ZIR instructions that are always either `noreturn` or `void`. |
| 1753 | .breakpoint, |
| 1754 | .fence, |
| 1755 | .dbg_stmt_node, |
| 1756 | .ensure_result_used, |
| 1757 | .ensure_result_non_error, |
| 1758 | .@"export", |
| 1759 | .set_eval_branch_quota, |
| 1760 | .compile_log, |
| 1761 | .ensure_err_payload_void, |
| 1762 | .@"break", |
| 1763 | .break_inline, |
| 1764 | .condbr, |
| 1765 | .condbr_inline, |
| 1766 | .compile_error, |
| 1767 | .ret_node, |
| 1768 | .ret_tok, |
| 1769 | .ret_coerce, |
| 1770 | .@"unreachable", |
| 1771 | .store, |
| 1772 | .store_node, |
| 1773 | .store_to_block_ptr, |
| 1774 | .store_to_inferred_ptr, |
| 1775 | .resolve_inferred_alloc, |
| 1776 | .repeat, |
| 1777 | .repeat_inline, |
| 1778 | .validate_struct_init_ptr, |
| 1779 | .validate_array_init_ptr, |
| 1780 | .panic, |
| 1781 | .set_align_stack, |
| 1782 | .set_cold, |
| 1783 | .set_float_mode, |
| 1784 | .set_runtime_safety, |
| 1785 | => break :b true, |
| 1786 | } |
| 1787 | } else switch (maybe_unused_result) { |
| 1788 | .none => unreachable, |
| 1777 | 1789 | |
| 1778 | | else => false, |
| 1779 | | }; |
| 1780 | | if (!elide_check) { |
| 1781 | | _ = try gz.addUnNode(.ensure_result_used, maybe_unused_result, statement); |
| 1782 | | } |
| 1790 | .void_value, |
| 1791 | .unreachable_value, |
| 1792 | => true, |
| 1793 | |
| 1794 | else => false, |
| 1795 | }; |
| 1796 | if (!elide_check) { |
| 1797 | _ = try gz.addUnNode(.ensure_result_used, maybe_unused_result, statement); |
| 1798 | } |
| 1799 | } |
| 1800 | |
| 1801 | fn genDefers( |
| 1802 | gz: *GenZir, |
| 1803 | outer_scope: *Scope, |
| 1804 | inner_scope: *Scope, |
| 1805 | err_code: Zir.Inst.Ref, |
| 1806 | ) InnerError!void { |
| 1807 | const astgen = gz.astgen; |
| 1808 | const tree = &astgen.file.tree; |
| 1809 | const node_datas = tree.nodes.items(.data); |
| 1810 | |
| 1811 | var scope = inner_scope; |
| 1812 | while (scope != outer_scope) { |
| 1813 | switch (scope.tag) { |
| 1814 | .gen_zir => scope = scope.cast(GenZir).?.parent, |
| 1815 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 1816 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| 1817 | .defer_normal => { |
| 1818 | const defer_scope = scope.cast(Scope.Defer).?; |
| 1819 | scope = defer_scope.parent; |
| 1820 | const expr_node = node_datas[defer_scope.defer_node].rhs; |
| 1821 | try unusedResultExpr(gz, defer_scope.parent, expr_node); |
| 1783 | 1822 | }, |
| 1823 | .defer_error => { |
| 1824 | const defer_scope = scope.cast(Scope.Defer).?; |
| 1825 | scope = defer_scope.parent; |
| 1826 | if (err_code == .none) continue; |
| 1827 | const expr_node = node_datas[defer_scope.defer_node].rhs; |
| 1828 | try unusedResultExpr(gz, defer_scope.parent, expr_node); |
| 1829 | }, |
| 1830 | else => unreachable, |
| 1784 | 1831 | } |
| 1785 | 1832 | } |
| 1786 | 1833 | } |
| 1787 | 1834 | |
| 1835 | fn deferStmt( |
| 1836 | gz: *GenZir, |
| 1837 | scope: *Scope, |
| 1838 | node: ast.Node.Index, |
| 1839 | block_arena: *Allocator, |
| 1840 | scope_tag: Scope.Tag, |
| 1841 | ) InnerError!*Scope { |
| 1842 | const defer_scope = try block_arena.create(Scope.Defer); |
| 1843 | defer_scope.* = .{ |
| 1844 | .base = .{ .tag = scope_tag }, |
| 1845 | .parent = scope, |
| 1846 | .defer_node = node, |
| 1847 | }; |
| 1848 | return &defer_scope.base; |
| 1849 | } |
| 1850 | |
| 1788 | 1851 | fn varDecl( |
| 1789 | 1852 | gz: *GenZir, |
| 1790 | 1853 | scope: *Scope, |
| ... | ... | @@ -1792,6 +1855,7 @@ fn varDecl( |
| 1792 | 1855 | block_arena: *Allocator, |
| 1793 | 1856 | var_decl: ast.full.VarDecl, |
| 1794 | 1857 | ) InnerError!*Scope { |
| 1858 | try emitDbgNode(gz, node); |
| 1795 | 1859 | const astgen = gz.astgen; |
| 1796 | 1860 | if (var_decl.comptime_token) |comptime_token| { |
| 1797 | 1861 | return astgen.failTok(comptime_token, "TODO implement comptime locals", .{}); |
| ... | ... | @@ -1841,6 +1905,7 @@ fn varDecl( |
| 1841 | 1905 | s = local_ptr.parent; |
| 1842 | 1906 | }, |
| 1843 | 1907 | .gen_zir => s = s.cast(GenZir).?.parent, |
| 1908 | .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent, |
| 1844 | 1909 | .file => break, |
| 1845 | 1910 | else => unreachable, |
| 1846 | 1911 | }; |
| ... | ... | @@ -1877,6 +1942,7 @@ fn varDecl( |
| 1877 | 1942 | .parent = scope, |
| 1878 | 1943 | .decl_node_index = gz.decl_node_index, |
| 1879 | 1944 | .force_comptime = gz.force_comptime, |
| 1945 | .ref_start_index = gz.ref_start_index, |
| 1880 | 1946 | .astgen = astgen, |
| 1881 | 1947 | }; |
| 1882 | 1948 | defer init_scope.instructions.deinit(gpa); |
| ... | ... | @@ -1984,7 +2050,14 @@ fn varDecl( |
| 1984 | 2050 | } |
| 1985 | 2051 | } |
| 1986 | 2052 | |
| 2053 | fn emitDbgNode(gz: *GenZir, node: ast.Node.Index) !void { |
| 2054 | if (!gz.force_comptime) { |
| 2055 | _ = try gz.addNode(.dbg_stmt_node, node); |
| 2056 | } |
| 2057 | } |
| 2058 | |
| 1987 | 2059 | fn assign(gz: *GenZir, scope: *Scope, infix_node: ast.Node.Index) InnerError!void { |
| 2060 | try emitDbgNode(gz, infix_node); |
| 1988 | 2061 | const astgen = gz.astgen; |
| 1989 | 2062 | const tree = &astgen.file.tree; |
| 1990 | 2063 | const node_datas = tree.nodes.items(.data); |
| ... | ... | @@ -2011,6 +2084,7 @@ fn assignOp( |
| 2011 | 2084 | infix_node: ast.Node.Index, |
| 2012 | 2085 | op_inst_tag: Zir.Inst.Tag, |
| 2013 | 2086 | ) InnerError!void { |
| 2087 | try emitDbgNode(gz, infix_node); |
| 2014 | 2088 | const astgen = gz.astgen; |
| 2015 | 2089 | const tree = &astgen.file.tree; |
| 2016 | 2090 | const node_datas = tree.nodes.items(.data); |
| ... | ... | @@ -2033,6 +2107,7 @@ fn assignShift( |
| 2033 | 2107 | infix_node: ast.Node.Index, |
| 2034 | 2108 | op_inst_tag: Zir.Inst.Tag, |
| 2035 | 2109 | ) InnerError!void { |
| 2110 | try emitDbgNode(gz, infix_node); |
| 2036 | 2111 | const astgen = gz.astgen; |
| 2037 | 2112 | const tree = &astgen.file.tree; |
| 2038 | 2113 | const node_datas = tree.nodes.items(.data); |
| ... | ... | @@ -2257,12 +2332,12 @@ fn fnDecl( |
| 2257 | 2332 | const param_types = try gpa.alloc(Zir.Inst.Ref, param_count); |
| 2258 | 2333 | defer gpa.free(param_types); |
| 2259 | 2334 | |
| 2260 | | var decl_gz: Scope.GenZir = .{ |
| 2335 | var decl_gz: GenZir = .{ |
| 2261 | 2336 | .force_comptime = true, |
| 2262 | 2337 | .decl_node_index = fn_proto.ast.proto_node, |
| 2263 | 2338 | .parent = &gz.base, |
| 2264 | 2339 | .astgen = astgen, |
| 2265 | | .ref_start_index = @intCast(u32, Zir.Inst.Ref.typed_value_map.len + param_count), |
| 2340 | .ref_start_index = @intCast(u32, Zir.Inst.Ref.typed_value_map.len), |
| 2266 | 2341 | }; |
| 2267 | 2342 | defer decl_gz.instructions.deinit(gpa); |
| 2268 | 2343 | |
| ... | ... | @@ -2357,7 +2432,7 @@ fn fnDecl( |
| 2357 | 2432 | return astgen.failTok(fn_proto.ast.fn_token, "non-extern function is variadic", .{}); |
| 2358 | 2433 | } |
| 2359 | 2434 | |
| 2360 | | var fn_gz: Scope.GenZir = .{ |
| 2435 | var fn_gz: GenZir = .{ |
| 2361 | 2436 | .force_comptime = false, |
| 2362 | 2437 | .decl_node_index = fn_proto.ast.proto_node, |
| 2363 | 2438 | .parent = &decl_gz.base, |
| ... | ... | @@ -2366,6 +2441,9 @@ fn fnDecl( |
| 2366 | 2441 | }; |
| 2367 | 2442 | defer fn_gz.instructions.deinit(gpa); |
| 2368 | 2443 | |
| 2444 | const prev_fn_block = astgen.fn_block; |
| 2445 | astgen.fn_block = &fn_gz; |
| 2446 | |
| 2369 | 2447 | // Iterate over the parameters. We put the param names as the first N |
| 2370 | 2448 | // items inside `extra` so that debug info later can refer to the parameter names |
| 2371 | 2449 | // even while the respective source code is unloaded. |
| ... | ... | @@ -2406,6 +2484,8 @@ fn fnDecl( |
| 2406 | 2484 | _ = try fn_gz.addUnTok(.ret_coerce, .void_value, tree.lastToken(body_node)); |
| 2407 | 2485 | } |
| 2408 | 2486 | |
| 2487 | astgen.fn_block = prev_fn_block; |
| 2488 | |
| 2409 | 2489 | break :func try decl_gz.addFunc(.{ |
| 2410 | 2490 | .src_node = fn_proto.ast.proto_node, |
| 2411 | 2491 | .ret_ty = return_type_inst, |
| ... | ... | @@ -2580,9 +2660,18 @@ fn testDecl( |
| 2580 | 2660 | scope: *Scope, |
| 2581 | 2661 | node: ast.Node.Index, |
| 2582 | 2662 | ) InnerError!void { |
| 2663 | const gpa = astgen.gpa; |
| 2583 | 2664 | const tree = &astgen.file.tree; |
| 2584 | 2665 | const node_datas = tree.nodes.items(.data); |
| 2585 | | const test_expr = node_datas[node].rhs; |
| 2666 | const body_node = node_datas[node].rhs; |
| 2667 | |
| 2668 | var decl_block: GenZir = .{ |
| 2669 | .force_comptime = true, |
| 2670 | .decl_node_index = node, |
| 2671 | .parent = &gz.base, |
| 2672 | .astgen = astgen, |
| 2673 | }; |
| 2674 | defer decl_block.instructions.deinit(gpa); |
| 2586 | 2675 | |
| 2587 | 2676 | const test_name: u32 = blk: { |
| 2588 | 2677 | const main_tokens = tree.nodes.items(.main_token); |
| ... | ... | @@ -2590,13 +2679,49 @@ fn testDecl( |
| 2590 | 2679 | const test_token = main_tokens[node]; |
| 2591 | 2680 | const str_lit_token = test_token + 1; |
| 2592 | 2681 | if (token_tags[str_lit_token] == .string_literal) { |
| 2593 | | break :blk (try gz.strLitAsString(str_lit_token)).index; |
| 2682 | break :blk (try decl_block.strLitAsString(str_lit_token)).index; |
| 2594 | 2683 | } |
| 2595 | 2684 | break :blk 0; |
| 2596 | 2685 | }; |
| 2597 | 2686 | |
| 2598 | | // TODO probably we want to put these into a block and store a list of them |
| 2599 | | const block_inst = try expr(gz, scope, .none, test_expr); |
| 2687 | var fn_block: GenZir = .{ |
| 2688 | .force_comptime = false, |
| 2689 | .decl_node_index = node, |
| 2690 | .parent = &decl_block.base, |
| 2691 | .astgen = astgen, |
| 2692 | }; |
| 2693 | defer fn_block.instructions.deinit(gpa); |
| 2694 | |
| 2695 | const prev_fn_block = astgen.fn_block; |
| 2696 | astgen.fn_block = &fn_block; |
| 2697 | |
| 2698 | const block_result = try expr(&fn_block, &fn_block.base, .none, body_node); |
| 2699 | if (fn_block.instructions.items.len == 0 or !fn_block.refIsNoReturn(block_result)) { |
| 2700 | // Since we are adding the return instruction here, we must handle the coercion. |
| 2701 | // We do this by using the `ret_coerce` instruction. |
| 2702 | _ = try fn_block.addUnTok(.ret_coerce, .void_value, tree.lastToken(body_node)); |
| 2703 | } |
| 2704 | |
| 2705 | astgen.fn_block = prev_fn_block; |
| 2706 | |
| 2707 | const func_inst = try decl_block.addFunc(.{ |
| 2708 | .src_node = node, |
| 2709 | .ret_ty = .void_type, |
| 2710 | .param_types = &[0]Zir.Inst.Ref{}, |
| 2711 | .body = fn_block.instructions.items, |
| 2712 | .cc = .none, |
| 2713 | .lib_name = 0, |
| 2714 | .is_var_args = false, |
| 2715 | .is_inferred_error = true, |
| 2716 | }); |
| 2717 | |
| 2718 | const block_inst = try gz.addBlock(.block_inline, node); |
| 2719 | _ = try decl_block.addBreak(.break_inline, block_inst, func_inst); |
| 2720 | try decl_block.setBlockBody(block_inst); |
| 2721 | |
| 2722 | // TODO collect these into a test decl list |
| 2723 | _ = test_name; |
| 2724 | _ = block_inst; |
| 2600 | 2725 | } |
| 2601 | 2726 | |
| 2602 | 2727 | fn structDeclInner( |
| ... | ... | @@ -2628,6 +2753,7 @@ fn structDeclInner( |
| 2628 | 2753 | .decl_node_index = node, |
| 2629 | 2754 | .astgen = astgen, |
| 2630 | 2755 | .force_comptime = true, |
| 2756 | .ref_start_index = gz.ref_start_index, |
| 2631 | 2757 | }; |
| 2632 | 2758 | defer block_scope.instructions.deinit(gpa); |
| 2633 | 2759 | |
| ... | ... | @@ -2943,6 +3069,7 @@ fn containerDecl( |
| 2943 | 3069 | .decl_node_index = node, |
| 2944 | 3070 | .astgen = astgen, |
| 2945 | 3071 | .force_comptime = true, |
| 3072 | .ref_start_index = gz.ref_start_index, |
| 2946 | 3073 | }; |
| 2947 | 3074 | defer block_scope.instructions.deinit(gpa); |
| 2948 | 3075 | |
| ... | ... | @@ -3168,6 +3295,7 @@ fn tryExpr( |
| 3168 | 3295 | .decl_node_index = parent_gz.decl_node_index, |
| 3169 | 3296 | .astgen = astgen, |
| 3170 | 3297 | .force_comptime = parent_gz.force_comptime, |
| 3298 | .ref_start_index = parent_gz.ref_start_index, |
| 3171 | 3299 | .instructions = .{}, |
| 3172 | 3300 | }; |
| 3173 | 3301 | block_scope.setBreakResultLoc(rl); |
| ... | ... | @@ -3200,11 +3328,13 @@ fn tryExpr( |
| 3200 | 3328 | .decl_node_index = parent_gz.decl_node_index, |
| 3201 | 3329 | .astgen = astgen, |
| 3202 | 3330 | .force_comptime = block_scope.force_comptime, |
| 3331 | .ref_start_index = parent_gz.ref_start_index, |
| 3203 | 3332 | .instructions = .{}, |
| 3204 | 3333 | }; |
| 3205 | 3334 | defer then_scope.instructions.deinit(astgen.gpa); |
| 3206 | 3335 | |
| 3207 | 3336 | const err_code = try then_scope.addUnNode(err_ops[1], operand, node); |
| 3337 | try genDefers(&then_scope, &astgen.fn_block.?.base, scope, err_code); |
| 3208 | 3338 | const then_result = try then_scope.addUnNode(.ret_node, err_code, node); |
| 3209 | 3339 | |
| 3210 | 3340 | var else_scope: GenZir = .{ |
| ... | ... | @@ -3212,6 +3342,7 @@ fn tryExpr( |
| 3212 | 3342 | .decl_node_index = parent_gz.decl_node_index, |
| 3213 | 3343 | .astgen = astgen, |
| 3214 | 3344 | .force_comptime = block_scope.force_comptime, |
| 3345 | .ref_start_index = parent_gz.ref_start_index, |
| 3215 | 3346 | .instructions = .{}, |
| 3216 | 3347 | }; |
| 3217 | 3348 | defer else_scope.instructions.deinit(astgen.gpa); |
| ... | ... | @@ -3264,6 +3395,7 @@ fn orelseCatchExpr( |
| 3264 | 3395 | .decl_node_index = parent_gz.decl_node_index, |
| 3265 | 3396 | .astgen = astgen, |
| 3266 | 3397 | .force_comptime = parent_gz.force_comptime, |
| 3398 | .ref_start_index = parent_gz.ref_start_index, |
| 3267 | 3399 | .instructions = .{}, |
| 3268 | 3400 | }; |
| 3269 | 3401 | block_scope.setBreakResultLoc(rl); |
| ... | ... | @@ -3300,6 +3432,7 @@ fn orelseCatchExpr( |
| 3300 | 3432 | .decl_node_index = parent_gz.decl_node_index, |
| 3301 | 3433 | .astgen = astgen, |
| 3302 | 3434 | .force_comptime = block_scope.force_comptime, |
| 3435 | .ref_start_index = parent_gz.ref_start_index, |
| 3303 | 3436 | .instructions = .{}, |
| 3304 | 3437 | }; |
| 3305 | 3438 | defer then_scope.instructions.deinit(astgen.gpa); |
| ... | ... | @@ -3332,6 +3465,7 @@ fn orelseCatchExpr( |
| 3332 | 3465 | .decl_node_index = parent_gz.decl_node_index, |
| 3333 | 3466 | .astgen = astgen, |
| 3334 | 3467 | .force_comptime = block_scope.force_comptime, |
| 3468 | .ref_start_index = parent_gz.ref_start_index, |
| 3335 | 3469 | .instructions = .{}, |
| 3336 | 3470 | }; |
| 3337 | 3471 | defer else_scope.instructions.deinit(astgen.gpa); |
| ... | ... | @@ -3532,6 +3666,7 @@ fn boolBinOp( |
| 3532 | 3666 | .decl_node_index = gz.decl_node_index, |
| 3533 | 3667 | .astgen = gz.astgen, |
| 3534 | 3668 | .force_comptime = gz.force_comptime, |
| 3669 | .ref_start_index = gz.ref_start_index, |
| 3535 | 3670 | }; |
| 3536 | 3671 | defer rhs_scope.instructions.deinit(gz.astgen.gpa); |
| 3537 | 3672 | const rhs = try expr(&rhs_scope, &rhs_scope.base, bool_rl, node_datas[node].rhs); |
| ... | ... | @@ -3558,6 +3693,7 @@ fn ifExpr( |
| 3558 | 3693 | .decl_node_index = parent_gz.decl_node_index, |
| 3559 | 3694 | .astgen = astgen, |
| 3560 | 3695 | .force_comptime = parent_gz.force_comptime, |
| 3696 | .ref_start_index = parent_gz.ref_start_index, |
| 3561 | 3697 | .instructions = .{}, |
| 3562 | 3698 | }; |
| 3563 | 3699 | block_scope.setBreakResultLoc(rl); |
| ... | ... | @@ -3608,6 +3744,7 @@ fn ifExpr( |
| 3608 | 3744 | .decl_node_index = parent_gz.decl_node_index, |
| 3609 | 3745 | .astgen = astgen, |
| 3610 | 3746 | .force_comptime = block_scope.force_comptime, |
| 3747 | .ref_start_index = parent_gz.ref_start_index, |
| 3611 | 3748 | .instructions = .{}, |
| 3612 | 3749 | }; |
| 3613 | 3750 | defer then_scope.instructions.deinit(astgen.gpa); |
| ... | ... | @@ -3662,6 +3799,7 @@ fn ifExpr( |
| 3662 | 3799 | .decl_node_index = parent_gz.decl_node_index, |
| 3663 | 3800 | .astgen = astgen, |
| 3664 | 3801 | .force_comptime = block_scope.force_comptime, |
| 3802 | .ref_start_index = parent_gz.ref_start_index, |
| 3665 | 3803 | .instructions = .{}, |
| 3666 | 3804 | }; |
| 3667 | 3805 | defer else_scope.instructions.deinit(astgen.gpa); |
| ... | ... | @@ -3812,6 +3950,7 @@ fn whileExpr( |
| 3812 | 3950 | .decl_node_index = parent_gz.decl_node_index, |
| 3813 | 3951 | .astgen = astgen, |
| 3814 | 3952 | .force_comptime = parent_gz.force_comptime, |
| 3953 | .ref_start_index = parent_gz.ref_start_index, |
| 3815 | 3954 | .instructions = .{}, |
| 3816 | 3955 | }; |
| 3817 | 3956 | loop_scope.setBreakResultLoc(rl); |
| ... | ... | @@ -3822,6 +3961,7 @@ fn whileExpr( |
| 3822 | 3961 | .decl_node_index = parent_gz.decl_node_index, |
| 3823 | 3962 | .astgen = astgen, |
| 3824 | 3963 | .force_comptime = loop_scope.force_comptime, |
| 3964 | .ref_start_index = parent_gz.ref_start_index, |
| 3825 | 3965 | .instructions = .{}, |
| 3826 | 3966 | }; |
| 3827 | 3967 | defer continue_scope.instructions.deinit(astgen.gpa); |
| ... | ... | @@ -3891,6 +4031,7 @@ fn whileExpr( |
| 3891 | 4031 | .decl_node_index = parent_gz.decl_node_index, |
| 3892 | 4032 | .astgen = astgen, |
| 3893 | 4033 | .force_comptime = continue_scope.force_comptime, |
| 4034 | .ref_start_index = parent_gz.ref_start_index, |
| 3894 | 4035 | .instructions = .{}, |
| 3895 | 4036 | }; |
| 3896 | 4037 | defer then_scope.instructions.deinit(astgen.gpa); |
| ... | ... | @@ -3942,6 +4083,7 @@ fn whileExpr( |
| 3942 | 4083 | .decl_node_index = parent_gz.decl_node_index, |
| 3943 | 4084 | .astgen = astgen, |
| 3944 | 4085 | .force_comptime = continue_scope.force_comptime, |
| 4086 | .ref_start_index = parent_gz.ref_start_index, |
| 3945 | 4087 | .instructions = .{}, |
| 3946 | 4088 | }; |
| 3947 | 4089 | defer else_scope.instructions.deinit(astgen.gpa); |
| ... | ... | @@ -4043,6 +4185,7 @@ fn forExpr( |
| 4043 | 4185 | .decl_node_index = parent_gz.decl_node_index, |
| 4044 | 4186 | .astgen = astgen, |
| 4045 | 4187 | .force_comptime = parent_gz.force_comptime, |
| 4188 | .ref_start_index = parent_gz.ref_start_index, |
| 4046 | 4189 | .instructions = .{}, |
| 4047 | 4190 | }; |
| 4048 | 4191 | loop_scope.setBreakResultLoc(rl); |
| ... | ... | @@ -4053,6 +4196,7 @@ fn forExpr( |
| 4053 | 4196 | .decl_node_index = parent_gz.decl_node_index, |
| 4054 | 4197 | .astgen = astgen, |
| 4055 | 4198 | .force_comptime = loop_scope.force_comptime, |
| 4199 | .ref_start_index = parent_gz.ref_start_index, |
| 4056 | 4200 | .instructions = .{}, |
| 4057 | 4201 | }; |
| 4058 | 4202 | defer cond_scope.instructions.deinit(astgen.gpa); |
| ... | ... | @@ -4096,6 +4240,7 @@ fn forExpr( |
| 4096 | 4240 | .decl_node_index = parent_gz.decl_node_index, |
| 4097 | 4241 | .astgen = astgen, |
| 4098 | 4242 | .force_comptime = cond_scope.force_comptime, |
| 4243 | .ref_start_index = parent_gz.ref_start_index, |
| 4099 | 4244 | .instructions = .{}, |
| 4100 | 4245 | }; |
| 4101 | 4246 | defer then_scope.instructions.deinit(astgen.gpa); |
| ... | ... | @@ -4141,6 +4286,7 @@ fn forExpr( |
| 4141 | 4286 | .decl_node_index = parent_gz.decl_node_index, |
| 4142 | 4287 | .astgen = astgen, |
| 4143 | 4288 | .force_comptime = cond_scope.force_comptime, |
| 4289 | .ref_start_index = parent_gz.ref_start_index, |
| 4144 | 4290 | .instructions = .{}, |
| 4145 | 4291 | }; |
| 4146 | 4292 | defer else_scope.instructions.deinit(astgen.gpa); |
| ... | ... | @@ -4443,6 +4589,7 @@ fn switchExpr( |
| 4443 | 4589 | .decl_node_index = parent_gz.decl_node_index, |
| 4444 | 4590 | .astgen = astgen, |
| 4445 | 4591 | .force_comptime = parent_gz.force_comptime, |
| 4592 | .ref_start_index = parent_gz.ref_start_index, |
| 4446 | 4593 | .instructions = .{}, |
| 4447 | 4594 | }; |
| 4448 | 4595 | block_scope.setBreakResultLoc(rl); |
| ... | ... | @@ -4457,6 +4604,7 @@ fn switchExpr( |
| 4457 | 4604 | .decl_node_index = parent_gz.decl_node_index, |
| 4458 | 4605 | .astgen = astgen, |
| 4459 | 4606 | .force_comptime = parent_gz.force_comptime, |
| 4607 | .ref_start_index = parent_gz.ref_start_index, |
| 4460 | 4608 | .instructions = .{}, |
| 4461 | 4609 | }; |
| 4462 | 4610 | defer case_scope.instructions.deinit(gpa); |
| ... | ... | @@ -4900,15 +5048,21 @@ fn ret(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref |
| 4900 | 5048 | const main_tokens = tree.nodes.items(.main_token); |
| 4901 | 5049 | |
| 4902 | 5050 | const operand_node = node_datas[node].lhs; |
| 4903 | | const operand: Zir.Inst.Ref = if (operand_node != 0) operand: { |
| 5051 | if (operand_node != 0) { |
| 4904 | 5052 | const rl: ResultLoc = if (nodeMayNeedMemoryLocation(tree, operand_node)) .{ |
| 4905 | 5053 | .ptr = try gz.addNodeExtended(.ret_ptr, node), |
| 4906 | 5054 | } else .{ |
| 4907 | 5055 | .ty = try gz.addNodeExtended(.ret_type, node), |
| 4908 | 5056 | }; |
| 4909 | | break :operand try expr(gz, scope, rl, operand_node); |
| 4910 | | } else .void_value; |
| 4911 | | _ = try gz.addUnNode(.ret_node, operand, node); |
| 5057 | const operand = try expr(gz, scope, rl, operand_node); |
| 5058 | // TODO check operand to see if we need to generate errdefers |
| 5059 | try genDefers(gz, &astgen.fn_block.?.base, scope, .none); |
| 5060 | _ = try gz.addUnNode(.ret_node, operand, node); |
| 5061 | return Zir.Inst.Ref.unreachable_value; |
| 5062 | } |
| 5063 | // Returning a void value; skip error defers. |
| 5064 | try genDefers(gz, &astgen.fn_block.?.base, scope, .none); |
| 5065 | _ = try gz.addUnNode(.ret_node, .void_value, node); |
| 4912 | 5066 | return Zir.Inst.Ref.unreachable_value; |
| 4913 | 5067 | } |
| 4914 | 5068 | |
| ... | ... | @@ -5309,6 +5463,7 @@ fn asRlPtr( |
| 5309 | 5463 | .decl_node_index = parent_gz.decl_node_index, |
| 5310 | 5464 | .astgen = astgen, |
| 5311 | 5465 | .force_comptime = parent_gz.force_comptime, |
| 5466 | .ref_start_index = parent_gz.ref_start_index, |
| 5312 | 5467 | .instructions = .{}, |
| 5313 | 5468 | }; |
| 5314 | 5469 | defer as_scope.instructions.deinit(astgen.gpa); |
| ... | ... | @@ -5998,6 +6153,7 @@ fn cImport( |
| 5998 | 6153 | .decl_node_index = gz.decl_node_index, |
| 5999 | 6154 | .astgen = astgen, |
| 6000 | 6155 | .force_comptime = true, |
| 6156 | .ref_start_index = gz.ref_start_index, |
| 6001 | 6157 | .instructions = .{}, |
| 6002 | 6158 | }; |
| 6003 | 6159 | defer block_scope.instructions.deinit(gpa); |
| ... | ... | @@ -6454,7 +6610,7 @@ fn rvalue( |
| 6454 | 6610 | |
| 6455 | 6611 | /// Given an identifier token, obtain the string for it. |
| 6456 | 6612 | /// If the token uses @"" syntax, parses as a string, reports errors if applicable, |
| 6457 | | /// and allocates the result within `scope.arena()`. |
| 6613 | /// and allocates the result within `astgen.arena`. |
| 6458 | 6614 | /// Otherwise, returns a reference to the source code bytes directly. |
| 6459 | 6615 | /// See also `appendIdentStr` and `parseStrLit`. |
| 6460 | 6616 | pub fn identifierTokenString(astgen: *AstGen, token: ast.TokenIndex) InnerError![]const u8 { |