| ... | @@ -68,7 +68,7 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *expr_node); | ... | @@ -68,7 +68,7 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *expr_node); |
| 68 | static LLVMValueRef gen_lvalue(CodeGen *g, AstNode *expr_node, AstNode *node, TypeTableEntry **out_type_entry); | 68 | static LLVMValueRef gen_lvalue(CodeGen *g, AstNode *expr_node, AstNode *node, TypeTableEntry **out_type_entry); |
| 69 | static LLVMValueRef gen_field_access_expr(CodeGen *g, AstNode *node, bool is_lvalue); | 69 | static LLVMValueRef gen_field_access_expr(CodeGen *g, AstNode *node, bool is_lvalue); |
| 70 | static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVariableDeclaration *var_decl, | 70 | static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVariableDeclaration *var_decl, |
| 71 | BlockContext *block_context, bool unwrap_maybe, LLVMValueRef *init_val); | 71 | bool unwrap_maybe, LLVMValueRef *init_val); |
| 72 | static LLVMValueRef gen_assign_raw(CodeGen *g, AstNode *source_node, BinOpType bin_op, | 72 | static LLVMValueRef gen_assign_raw(CodeGen *g, AstNode *source_node, BinOpType bin_op, |
| 73 | LLVMValueRef target_ref, LLVMValueRef value, | 73 | LLVMValueRef target_ref, LLVMValueRef value, |
| 74 | TypeTableEntry *op1_type, TypeTableEntry *op2_type); | 74 | TypeTableEntry *op1_type, TypeTableEntry *op2_type); |
| ... | @@ -82,10 +82,8 @@ static TypeTableEntry *get_type_for_type_node(AstNode *node) { | ... | @@ -82,10 +82,8 @@ static TypeTableEntry *get_type_for_type_node(AstNode *node) { |
| 82 | } | 82 | } |
| 83 | | 83 | |
| 84 | static void add_debug_source_node(CodeGen *g, AstNode *node) { | 84 | static void add_debug_source_node(CodeGen *g, AstNode *node) { |
| 85 | if (!g->cur_block_context) | 85 | assert(node->block_context); |
| 86 | return; | 86 | LLVMZigSetCurrentDebugLocation(g->builder, node->line + 1, node->column + 1, node->block_context->di_scope); |
| 87 | LLVMZigSetCurrentDebugLocation(g->builder, node->line + 1, node->column + 1, | | |
| 88 | g->cur_block_context->di_scope); | | |
| 89 | } | 87 | } |
| 90 | | 88 | |
| 91 | static TypeTableEntry *get_expr_type(AstNode *node) { | 89 | static TypeTableEntry *get_expr_type(AstNode *node) { |
| ... | @@ -557,7 +555,7 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou | ... | @@ -557,7 +555,7 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou |
| 557 | | 555 | |
| 558 | LLVMValueRef struct_ptr; | 556 | LLVMValueRef struct_ptr; |
| 559 | if (struct_expr_node->type == NodeTypeSymbol) { | 557 | if (struct_expr_node->type == NodeTypeSymbol) { |
| 560 | VariableTableEntry *var = find_variable(get_resolved_expr(struct_expr_node)->block_context, | 558 | VariableTableEntry *var = find_variable(struct_expr_node->block_context, |
| 561 | &struct_expr_node->data.symbol_expr.symbol); | 559 | &struct_expr_node->data.symbol_expr.symbol); |
| 562 | assert(var); | 560 | assert(var); |
| 563 | | 561 | |
| ... | @@ -745,7 +743,7 @@ static LLVMValueRef gen_lvalue(CodeGen *g, AstNode *expr_node, AstNode *node, | ... | @@ -745,7 +743,7 @@ static LLVMValueRef gen_lvalue(CodeGen *g, AstNode *expr_node, AstNode *node, |
| 745 | LLVMValueRef target_ref; | 743 | LLVMValueRef target_ref; |
| 746 | | 744 | |
| 747 | if (node->type == NodeTypeSymbol) { | 745 | if (node->type == NodeTypeSymbol) { |
| 748 | VariableTableEntry *var = find_variable(get_resolved_expr(expr_node)->block_context, | 746 | VariableTableEntry *var = find_variable(expr_node->block_context, |
| 749 | &node->data.symbol_expr.symbol); | 747 | &node->data.symbol_expr.symbol); |
| 750 | assert(var); | 748 | assert(var); |
| 751 | // semantic checking ensures no variables are constant | 749 | // semantic checking ensures no variables are constant |
| ... | @@ -1522,33 +1520,24 @@ static LLVMValueRef gen_if_var_expr(CodeGen *g, AstNode *node) { | ... | @@ -1522,33 +1520,24 @@ static LLVMValueRef gen_if_var_expr(CodeGen *g, AstNode *node) { |
| 1522 | assert(node->type == NodeTypeIfVarExpr); | 1520 | assert(node->type == NodeTypeIfVarExpr); |
| 1523 | assert(node->data.if_var_expr.var_decl.expr); | 1521 | assert(node->data.if_var_expr.var_decl.expr); |
| 1524 | | 1522 | |
| 1525 | BlockContext *old_block_context = g->cur_block_context; | | |
| 1526 | BlockContext *new_block_context = node->data.if_var_expr.block_context; | | |
| 1527 | | | |
| 1528 | LLVMValueRef init_val; | 1523 | LLVMValueRef init_val; |
| 1529 | gen_var_decl_raw(g, node, &node->data.if_var_expr.var_decl, new_block_context, true, &init_val); | 1524 | gen_var_decl_raw(g, node, &node->data.if_var_expr.var_decl, true, &init_val); |
| 1530 | | 1525 | |
| 1531 | // test if value is the maybe state | 1526 | // test if value is the maybe state |
| 1532 | add_debug_source_node(g, node); | 1527 | add_debug_source_node(g, node); |
| 1533 | LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, init_val, 1, ""); | 1528 | LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, init_val, 1, ""); |
| 1534 | LLVMValueRef cond_value = LLVMBuildLoad(g->builder, maybe_field_ptr, ""); | 1529 | LLVMValueRef cond_value = LLVMBuildLoad(g->builder, maybe_field_ptr, ""); |
| 1535 | | 1530 | |
| 1536 | g->cur_block_context = new_block_context; | | |
| 1537 | | | |
| 1538 | LLVMValueRef return_value = gen_if_bool_expr_raw(g, node, cond_value, | 1531 | LLVMValueRef return_value = gen_if_bool_expr_raw(g, node, cond_value, |
| 1539 | node->data.if_var_expr.then_block, | 1532 | node->data.if_var_expr.then_block, |
| 1540 | node->data.if_var_expr.else_node); | 1533 | node->data.if_var_expr.else_node); |
| 1541 | | 1534 | |
| 1542 | g->cur_block_context = old_block_context; | | |
| 1543 | return return_value; | 1535 | return return_value; |
| 1544 | } | 1536 | } |
| 1545 | | 1537 | |
| 1546 | static LLVMValueRef gen_block(CodeGen *g, AstNode *block_node, TypeTableEntry *implicit_return_type) { | 1538 | static LLVMValueRef gen_block(CodeGen *g, AstNode *block_node, TypeTableEntry *implicit_return_type) { |
| 1547 | assert(block_node->type == NodeTypeBlock); | 1539 | assert(block_node->type == NodeTypeBlock); |
| 1548 | | 1540 | |
| 1549 | BlockContext *old_block_context = g->cur_block_context; | | |
| 1550 | g->cur_block_context = block_node->data.block.block_context; | | |
| 1551 | | | |
| 1552 | LLVMValueRef return_value; | 1541 | LLVMValueRef return_value; |
| 1553 | for (int i = 0; i < block_node->data.block.statements.length; i += 1) { | 1542 | for (int i = 0; i < block_node->data.block.statements.length; i += 1) { |
| 1554 | AstNode *statement_node = block_node->data.block.statements.at(i); | 1543 | AstNode *statement_node = block_node->data.block.statements.at(i); |
| ... | @@ -1556,12 +1545,10 @@ static LLVMValueRef gen_block(CodeGen *g, AstNode *block_node, TypeTableEntry *i | ... | @@ -1556,12 +1545,10 @@ static LLVMValueRef gen_block(CodeGen *g, AstNode *block_node, TypeTableEntry *i |
| 1556 | } | 1545 | } |
| 1557 | | 1546 | |
| 1558 | if (implicit_return_type && implicit_return_type->id != TypeTableEntryIdUnreachable) { | 1547 | if (implicit_return_type && implicit_return_type->id != TypeTableEntryIdUnreachable) { |
| 1559 | gen_return(g, block_node, return_value); | 1548 | return gen_return(g, block_node, return_value); |
| | 1549 | } else { |
| | 1550 | return return_value; |
| 1560 | } | 1551 | } |
| 1561 | | | |
| 1562 | g->cur_block_context = old_block_context; | | |
| 1563 | | | |
| 1564 | return return_value; | | |
| 1565 | } | 1552 | } |
| 1566 | | 1553 | |
| 1567 | static int find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok) { | 1554 | static int find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok) { |
| ... | @@ -1646,9 +1633,7 @@ static LLVMValueRef gen_asm_expr(CodeGen *g, AstNode *node) { | ... | @@ -1646,9 +1633,7 @@ static LLVMValueRef gen_asm_expr(CodeGen *g, AstNode *node) { |
| 1646 | } | 1633 | } |
| 1647 | | 1634 | |
| 1648 | if (!is_return) { | 1635 | if (!is_return) { |
| 1649 | VariableTableEntry *variable = find_variable( | 1636 | VariableTableEntry *variable = find_variable( node->block_context, &asm_output->variable_name); |
| 1650 | get_resolved_expr(node)->block_context, | | |
| 1651 | &asm_output->variable_name); | | |
| 1652 | assert(variable); | 1637 | assert(variable); |
| 1653 | param_types[param_index] = LLVMTypeOf(variable->value_ref); | 1638 | param_types[param_index] = LLVMTypeOf(variable->value_ref); |
| 1654 | param_values[param_index] = variable->value_ref; | 1639 | param_values[param_index] = variable->value_ref; |
| ... | @@ -1763,13 +1748,10 @@ static LLVMValueRef gen_while_expr(CodeGen *g, AstNode *node) { | ... | @@ -1763,13 +1748,10 @@ static LLVMValueRef gen_while_expr(CodeGen *g, AstNode *node) { |
| 1763 | assert(node->data.while_expr.condition); | 1748 | assert(node->data.while_expr.condition); |
| 1764 | assert(node->data.while_expr.body); | 1749 | assert(node->data.while_expr.body); |
| 1765 | | 1750 | |
| 1766 | BlockContext *old_block_context = g->cur_block_context; | | |
| 1767 | | | |
| 1768 | bool condition_always_true = node->data.while_expr.condition_always_true; | 1751 | bool condition_always_true = node->data.while_expr.condition_always_true; |
| 1769 | bool contains_break = node->data.while_expr.contains_break; | 1752 | bool contains_break = node->data.while_expr.contains_break; |
| 1770 | if (condition_always_true) { | 1753 | if (condition_always_true) { |
| 1771 | // generate a forever loop | 1754 | // generate a forever loop |
| 1772 | g->cur_block_context = node->data.while_expr.block_context; | | |
| 1773 | | 1755 | |
| 1774 | LLVMBasicBlockRef body_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileBody"); | 1756 | LLVMBasicBlockRef body_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileBody"); |
| 1775 | LLVMBasicBlockRef end_block = nullptr; | 1757 | LLVMBasicBlockRef end_block = nullptr; |
| ... | @@ -1806,7 +1788,6 @@ static LLVMValueRef gen_while_expr(CodeGen *g, AstNode *node) { | ... | @@ -1806,7 +1788,6 @@ static LLVMValueRef gen_while_expr(CodeGen *g, AstNode *node) { |
| 1806 | LLVMBuildBr(g->builder, cond_block); | 1788 | LLVMBuildBr(g->builder, cond_block); |
| 1807 | | 1789 | |
| 1808 | LLVMPositionBuilderAtEnd(g->builder, cond_block); | 1790 | LLVMPositionBuilderAtEnd(g->builder, cond_block); |
| 1809 | g->cur_block_context = old_block_context; | | |
| 1810 | LLVMValueRef cond_val = gen_expr(g, node->data.while_expr.condition); | 1791 | LLVMValueRef cond_val = gen_expr(g, node->data.while_expr.condition); |
| 1811 | add_debug_source_node(g, node->data.while_expr.condition); | 1792 | add_debug_source_node(g, node->data.while_expr.condition); |
| 1812 | LLVMBuildCondBr(g->builder, cond_val, body_block, end_block); | 1793 | LLVMBuildCondBr(g->builder, cond_val, body_block, end_block); |
| ... | @@ -1814,7 +1795,6 @@ static LLVMValueRef gen_while_expr(CodeGen *g, AstNode *node) { | ... | @@ -1814,7 +1795,6 @@ static LLVMValueRef gen_while_expr(CodeGen *g, AstNode *node) { |
| 1814 | LLVMPositionBuilderAtEnd(g->builder, body_block); | 1795 | LLVMPositionBuilderAtEnd(g->builder, body_block); |
| 1815 | g->break_block_stack.append(end_block); | 1796 | g->break_block_stack.append(end_block); |
| 1816 | g->continue_block_stack.append(cond_block); | 1797 | g->continue_block_stack.append(cond_block); |
| 1817 | g->cur_block_context = node->data.while_expr.block_context; | | |
| 1818 | gen_expr(g, node->data.while_expr.body); | 1798 | gen_expr(g, node->data.while_expr.body); |
| 1819 | g->break_block_stack.pop(); | 1799 | g->break_block_stack.pop(); |
| 1820 | g->continue_block_stack.pop(); | 1800 | g->continue_block_stack.pop(); |
| ... | @@ -1826,7 +1806,6 @@ static LLVMValueRef gen_while_expr(CodeGen *g, AstNode *node) { | ... | @@ -1826,7 +1806,6 @@ static LLVMValueRef gen_while_expr(CodeGen *g, AstNode *node) { |
| 1826 | LLVMPositionBuilderAtEnd(g->builder, end_block); | 1806 | LLVMPositionBuilderAtEnd(g->builder, end_block); |
| 1827 | } | 1807 | } |
| 1828 | | 1808 | |
| 1829 | g->cur_block_context = old_block_context; | | |
| 1830 | return nullptr; | 1809 | return nullptr; |
| 1831 | } | 1810 | } |
| 1832 | | 1811 | |
| ... | @@ -1845,8 +1824,6 @@ static LLVMValueRef gen_for_expr(CodeGen *g, AstNode *node) { | ... | @@ -1845,8 +1824,6 @@ static LLVMValueRef gen_for_expr(CodeGen *g, AstNode *node) { |
| 1845 | LLVMValueRef index_ptr = index_var->value_ref; | 1824 | LLVMValueRef index_ptr = index_var->value_ref; |
| 1846 | LLVMValueRef one_const = LLVMConstInt(g->builtin_types.entry_isize->type_ref, 1, false); | 1825 | LLVMValueRef one_const = LLVMConstInt(g->builtin_types.entry_isize->type_ref, 1, false); |
| 1847 | | 1826 | |
| 1848 | BlockContext *old_block_context = g->cur_block_context; | | |
| 1849 | | | |
| 1850 | LLVMBasicBlockRef cond_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ForCond"); | 1827 | LLVMBasicBlockRef cond_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ForCond"); |
| 1851 | LLVMBasicBlockRef body_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ForBody"); | 1828 | LLVMBasicBlockRef body_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ForBody"); |
| 1852 | LLVMBasicBlockRef end_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ForEnd"); | 1829 | LLVMBasicBlockRef end_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ForEnd"); |
| ... | @@ -1884,7 +1861,6 @@ static LLVMValueRef gen_for_expr(CodeGen *g, AstNode *node) { | ... | @@ -1884,7 +1861,6 @@ static LLVMValueRef gen_for_expr(CodeGen *g, AstNode *node) { |
| 1884 | elem_var->type, child_type); | 1861 | elem_var->type, child_type); |
| 1885 | g->break_block_stack.append(end_block); | 1862 | g->break_block_stack.append(end_block); |
| 1886 | g->continue_block_stack.append(cond_block); | 1863 | g->continue_block_stack.append(cond_block); |
| 1887 | g->cur_block_context = node->data.for_expr.block_context; | | |
| 1888 | gen_expr(g, node->data.for_expr.body); | 1864 | gen_expr(g, node->data.for_expr.body); |
| 1889 | g->break_block_stack.pop(); | 1865 | g->break_block_stack.pop(); |
| 1890 | g->continue_block_stack.pop(); | 1866 | g->continue_block_stack.pop(); |
| ... | @@ -1896,7 +1872,6 @@ static LLVMValueRef gen_for_expr(CodeGen *g, AstNode *node) { | ... | @@ -1896,7 +1872,6 @@ static LLVMValueRef gen_for_expr(CodeGen *g, AstNode *node) { |
| 1896 | } | 1872 | } |
| 1897 | | 1873 | |
| 1898 | LLVMPositionBuilderAtEnd(g->builder, end_block); | 1874 | LLVMPositionBuilderAtEnd(g->builder, end_block); |
| 1899 | g->cur_block_context = old_block_context; | | |
| 1900 | return nullptr; | 1875 | return nullptr; |
| 1901 | } | 1876 | } |
| 1902 | | 1877 | |
| ... | @@ -1917,9 +1892,9 @@ static LLVMValueRef gen_continue(CodeGen *g, AstNode *node) { | ... | @@ -1917,9 +1892,9 @@ static LLVMValueRef gen_continue(CodeGen *g, AstNode *node) { |
| 1917 | } | 1892 | } |
| 1918 | | 1893 | |
| 1919 | static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVariableDeclaration *var_decl, | 1894 | static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVariableDeclaration *var_decl, |
| 1920 | BlockContext *block_context, bool unwrap_maybe, LLVMValueRef *init_value) | 1895 | bool unwrap_maybe, LLVMValueRef *init_value) |
| 1921 | { | 1896 | { |
| 1922 | VariableTableEntry *variable = find_variable(block_context, &var_decl->symbol); | 1897 | VariableTableEntry *variable = var_decl->variable; |
| 1923 | | 1898 | |
| 1924 | assert(variable); | 1899 | assert(variable); |
| 1925 | assert(variable->is_ptr); | 1900 | assert(variable->is_ptr); |
| ... | @@ -2010,7 +1985,7 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa | ... | @@ -2010,7 +1985,7 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa |
| 2010 | } | 1985 | } |
| 2011 | | 1986 | |
| 2012 | LLVMZigDILocation *debug_loc = LLVMZigGetDebugLoc(source_node->line + 1, source_node->column + 1, | 1987 | LLVMZigDILocation *debug_loc = LLVMZigGetDebugLoc(source_node->line + 1, source_node->column + 1, |
| 2013 | g->cur_block_context->di_scope); | 1988 | source_node->block_context->di_scope); |
| 2014 | LLVMZigInsertDeclareAtEnd(g->dbuilder, variable->value_ref, variable->di_loc_var, debug_loc, | 1989 | LLVMZigInsertDeclareAtEnd(g->dbuilder, variable->value_ref, variable->di_loc_var, debug_loc, |
| 2015 | LLVMGetInsertBlock(g->builder)); | 1990 | LLVMGetInsertBlock(g->builder)); |
| 2016 | return nullptr; | 1991 | return nullptr; |
| ... | @@ -2028,8 +2003,7 @@ static LLVMValueRef gen_var_decl_expr(CodeGen *g, AstNode *node) { | ... | @@ -2028,8 +2003,7 @@ static LLVMValueRef gen_var_decl_expr(CodeGen *g, AstNode *node) { |
| 2028 | } | 2003 | } |
| 2029 | | 2004 | |
| 2030 | LLVMValueRef init_val; | 2005 | LLVMValueRef init_val; |
| 2031 | return gen_var_decl_raw(g, node, &node->data.variable_declaration, | 2006 | return gen_var_decl_raw(g, node, &node->data.variable_declaration, false, &init_val); |
| 2032 | get_resolved_expr(node)->block_context, false, &init_val); | | |
| 2033 | } | 2007 | } |
| 2034 | | 2008 | |
| 2035 | static LLVMValueRef gen_symbol(CodeGen *g, AstNode *node) { | 2009 | static LLVMValueRef gen_symbol(CodeGen *g, AstNode *node) { |
| ... | @@ -2498,8 +2472,6 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -2498,8 +2472,6 @@ static void do_code_gen(CodeGen *g) { |
| 2498 | block_context->di_scope = LLVMZigLexicalBlockToScope(di_block); | 2472 | block_context->di_scope = LLVMZigLexicalBlockToScope(di_block); |
| 2499 | } | 2473 | } |
| 2500 | | 2474 | |
| 2501 | g->cur_block_context = block_context; | | |
| 2502 | | | |
| 2503 | for (int var_i = 0; var_i < block_context->variable_list.length; var_i += 1) { | 2475 | for (int var_i = 0; var_i < block_context->variable_list.length; var_i += 1) { |
| 2504 | VariableTableEntry *var = block_context->variable_list.at(var_i); | 2476 | VariableTableEntry *var = block_context->variable_list.at(var_i); |
| 2505 | | 2477 | |