| ... | @@ -31,8 +31,8 @@ struct IrAnalyze { | ... | @@ -31,8 +31,8 @@ struct IrAnalyze { |
| 31 | IrBasicBlock *const_predecessor_bb; | 31 | IrBasicBlock *const_predecessor_bb; |
| 32 | }; | 32 | }; |
| 33 | | 33 | |
| 34 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *scope); | 34 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); |
| 35 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockContext *block_context, | 35 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, |
| 36 | LValPurpose lval); | 36 | LValPurpose lval); |
| 37 | static TypeTableEntry *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction); | 37 | static TypeTableEntry *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction); |
| 38 | | 38 | |
| ... | @@ -451,7 +451,7 @@ static IrInstruction *ir_build_const_import(IrBuilder *irb, AstNode *source_node | ... | @@ -451,7 +451,7 @@ static IrInstruction *ir_build_const_import(IrBuilder *irb, AstNode *source_node |
| 451 | return &const_instruction->base; | 451 | return &const_instruction->base; |
| 452 | } | 452 | } |
| 453 | | 453 | |
| 454 | static IrInstruction *ir_build_const_scope(IrBuilder *irb, AstNode *source_node, BlockContext *scope) { | 454 | static IrInstruction *ir_build_const_scope(IrBuilder *irb, AstNode *source_node, Scope *scope) { |
| 455 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); | 455 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); |
| 456 | const_instruction->base.type_entry = irb->codegen->builtin_types.entry_block; | 456 | const_instruction->base.type_entry = irb->codegen->builtin_types.entry_block; |
| 457 | const_instruction->base.static_value.special = ConstValSpecialStatic; | 457 | const_instruction->base.static_value.special = ConstValSpecialStatic; |
| ... | @@ -1211,7 +1211,7 @@ static IrInstruction *ir_build_ref_from(IrBuilder *irb, IrInstruction *old_instr | ... | @@ -1211,7 +1211,7 @@ static IrInstruction *ir_build_ref_from(IrBuilder *irb, IrInstruction *old_instr |
| 1211 | return new_instruction; | 1211 | return new_instruction; |
| 1212 | } | 1212 | } |
| 1213 | | 1213 | |
| 1214 | static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, BlockContext *outer_block, | 1214 | static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_block, Scope *outer_block, |
| 1215 | bool gen_error_defers, bool gen_maybe_defers) | 1215 | bool gen_error_defers, bool gen_maybe_defers) |
| 1216 | { | 1216 | { |
| 1217 | while (inner_block != outer_block) { | 1217 | while (inner_block != outer_block) { |
| ... | @@ -1221,7 +1221,7 @@ static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, B | ... | @@ -1221,7 +1221,7 @@ static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, B |
| 1221 | (gen_maybe_defers && inner_block->node->data.defer.kind == ReturnKindMaybe))) | 1221 | (gen_maybe_defers && inner_block->node->data.defer.kind == ReturnKindMaybe))) |
| 1222 | { | 1222 | { |
| 1223 | AstNode *defer_expr_node = inner_block->node->data.defer.expr; | 1223 | AstNode *defer_expr_node = inner_block->node->data.defer.expr; |
| 1224 | ir_gen_node(irb, defer_expr_node, defer_expr_node->block_context); | 1224 | ir_gen_node(irb, defer_expr_node, defer_expr_node->scope); |
| 1225 | } | 1225 | } |
| 1226 | inner_block = inner_block->parent; | 1226 | inner_block = inner_block->parent; |
| 1227 | } | 1227 | } |
| ... | @@ -1230,7 +1230,7 @@ static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, B | ... | @@ -1230,7 +1230,7 @@ static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, B |
| 1230 | static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *node) { | 1230 | static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *node) { |
| 1231 | assert(node->type == NodeTypeReturnExpr); | 1231 | assert(node->type == NodeTypeReturnExpr); |
| 1232 | | 1232 | |
| 1233 | BlockContext *scope = node->block_context; | 1233 | Scope *scope = node->scope; |
| 1234 | | 1234 | |
| 1235 | if (!scope->fn_entry) { | 1235 | if (!scope->fn_entry) { |
| 1236 | add_node_error(irb->codegen, node, buf_sprintf("return expression outside function definition")); | 1236 | add_node_error(irb->codegen, node, buf_sprintf("return expression outside function definition")); |
| ... | @@ -1264,11 +1264,11 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { | ... | @@ -1264,11 +1264,11 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { |
| 1264 | irb->current_basic_block = basic_block; | 1264 | irb->current_basic_block = basic_block; |
| 1265 | } | 1265 | } |
| 1266 | | 1266 | |
| 1267 | static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, BlockContext *scope, | 1267 | static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, Scope *scope, |
| 1268 | Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, bool is_inline) | 1268 | Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, bool is_inline) |
| 1269 | { | 1269 | { |
| 1270 | VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1); | 1270 | VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1); |
| 1271 | variable_entry->block_context = scope; | 1271 | variable_entry->scope = scope; |
| 1272 | variable_entry->import = node->owner; | 1272 | variable_entry->import = node->owner; |
| 1273 | variable_entry->shadowable = is_shadowable; | 1273 | variable_entry->shadowable = is_shadowable; |
| 1274 | variable_entry->mem_slot_index = SIZE_MAX; | 1274 | variable_entry->mem_slot_index = SIZE_MAX; |
| ... | @@ -1316,7 +1316,7 @@ static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, BlockC | ... | @@ -1316,7 +1316,7 @@ static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, BlockC |
| 1316 | } | 1316 | } |
| 1317 | | 1317 | |
| 1318 | // Set name to nullptr to make the variable anonymous (not visible to programmer). | 1318 | // Set name to nullptr to make the variable anonymous (not visible to programmer). |
| 1319 | static VariableTableEntry *ir_add_local_var(IrBuilder *irb, AstNode *node, BlockContext *scope, Buf *name, | 1319 | static VariableTableEntry *ir_add_local_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *name, |
| 1320 | bool src_is_const, bool gen_is_const, bool is_shadowable, bool is_inline) | 1320 | bool src_is_const, bool gen_is_const, bool is_shadowable, bool is_inline) |
| 1321 | { | 1321 | { |
| 1322 | VariableTableEntry *var = add_local_var(irb->codegen, node, scope, name, | 1322 | VariableTableEntry *var = add_local_var(irb->codegen, node, scope, name, |
| ... | @@ -1329,41 +1329,41 @@ static VariableTableEntry *ir_add_local_var(IrBuilder *irb, AstNode *node, Block | ... | @@ -1329,41 +1329,41 @@ static VariableTableEntry *ir_add_local_var(IrBuilder *irb, AstNode *node, Block |
| 1329 | static IrInstruction *ir_gen_block(IrBuilder *irb, AstNode *block_node) { | 1329 | static IrInstruction *ir_gen_block(IrBuilder *irb, AstNode *block_node) { |
| 1330 | assert(block_node->type == NodeTypeBlock); | 1330 | assert(block_node->type == NodeTypeBlock); |
| 1331 | | 1331 | |
| 1332 | BlockContext *parent_context = block_node->block_context; | 1332 | Scope *parent_scope = block_node->scope; |
| 1333 | BlockContext *outer_block_context = new_block_context(block_node, parent_context); | 1333 | Scope *outer_block_scope = new_scope(block_node, parent_scope); |
| 1334 | BlockContext *child_context = outer_block_context; | 1334 | Scope *child_scope = outer_block_scope; |
| 1335 | | 1335 | |
| 1336 | IrInstruction *return_value = nullptr; | 1336 | IrInstruction *return_value = nullptr; |
| 1337 | for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) { | 1337 | for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) { |
| 1338 | AstNode *statement_node = block_node->data.block.statements.at(i); | 1338 | AstNode *statement_node = block_node->data.block.statements.at(i); |
| 1339 | return_value = ir_gen_node(irb, statement_node, child_context); | 1339 | return_value = ir_gen_node(irb, statement_node, child_scope); |
| 1340 | if (statement_node->type == NodeTypeDefer && return_value != irb->codegen->invalid_instruction) { | 1340 | if (statement_node->type == NodeTypeDefer && return_value != irb->codegen->invalid_instruction) { |
| 1341 | // defer starts a new block context | 1341 | // defer starts a new block context |
| 1342 | child_context = statement_node->data.defer.child_block; | 1342 | child_scope = statement_node->data.defer.child_block; |
| 1343 | assert(child_context); | 1343 | assert(child_scope); |
| 1344 | } | 1344 | } |
| 1345 | } | 1345 | } |
| 1346 | | 1346 | |
| 1347 | if (!return_value) | 1347 | if (!return_value) |
| 1348 | return_value = ir_build_const_void(irb, block_node); | 1348 | return_value = ir_build_const_void(irb, block_node); |
| 1349 | | 1349 | |
| 1350 | ir_gen_defers_for_block(irb, child_context, outer_block_context, false, false); | 1350 | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false, false); |
| 1351 | | 1351 | |
| 1352 | return return_value; | 1352 | return return_value; |
| 1353 | } | 1353 | } |
| 1354 | | 1354 | |
| 1355 | static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, AstNode *node, IrBinOp op_id) { | 1355 | static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, AstNode *node, IrBinOp op_id) { |
| 1356 | IrInstruction *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, node->block_context); | 1356 | IrInstruction *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, node->scope); |
| 1357 | IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, node->block_context); | 1357 | IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, node->scope); |
| 1358 | return ir_build_bin_op(irb, node, op_id, op1, op2); | 1358 | return ir_build_bin_op(irb, node, op_id, op1, op2); |
| 1359 | } | 1359 | } |
| 1360 | | 1360 | |
| 1361 | static IrInstruction *ir_gen_assign(IrBuilder *irb, AstNode *node) { | 1361 | static IrInstruction *ir_gen_assign(IrBuilder *irb, AstNode *node) { |
| 1362 | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, node->block_context, LValPurposeAssign); | 1362 | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, node->scope, LValPurposeAssign); |
| 1363 | if (lvalue == irb->codegen->invalid_instruction) | 1363 | if (lvalue == irb->codegen->invalid_instruction) |
| 1364 | return lvalue; | 1364 | return lvalue; |
| 1365 | | 1365 | |
| 1366 | IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, node->block_context); | 1366 | IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, node->scope); |
| 1367 | if (rvalue == irb->codegen->invalid_instruction) | 1367 | if (rvalue == irb->codegen->invalid_instruction) |
| 1368 | return rvalue; | 1368 | return rvalue; |
| 1369 | | 1369 | |
| ... | @@ -1372,11 +1372,11 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, AstNode *node) { | ... | @@ -1372,11 +1372,11 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, AstNode *node) { |
| 1372 | } | 1372 | } |
| 1373 | | 1373 | |
| 1374 | static IrInstruction *ir_gen_assign_op(IrBuilder *irb, AstNode *node, IrBinOp op_id) { | 1374 | static IrInstruction *ir_gen_assign_op(IrBuilder *irb, AstNode *node, IrBinOp op_id) { |
| 1375 | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, node->block_context, LValPurposeAssign); | 1375 | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, node->scope, LValPurposeAssign); |
| 1376 | if (lvalue == irb->codegen->invalid_instruction) | 1376 | if (lvalue == irb->codegen->invalid_instruction) |
| 1377 | return lvalue; | 1377 | return lvalue; |
| 1378 | IrInstruction *op1 = ir_build_load_ptr(irb, node->data.bin_op_expr.op1, lvalue); | 1378 | IrInstruction *op1 = ir_build_load_ptr(irb, node->data.bin_op_expr.op1, lvalue); |
| 1379 | IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, node->block_context); | 1379 | IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, node->scope); |
| 1380 | if (op2 == irb->codegen->invalid_instruction) | 1380 | if (op2 == irb->codegen->invalid_instruction) |
| 1381 | return op2; | 1381 | return op2; |
| 1382 | IrInstruction *result = ir_build_bin_op(irb, node, op_id, op1, op2); | 1382 | IrInstruction *result = ir_build_bin_op(irb, node, op_id, op1, op2); |
| ... | @@ -1498,7 +1498,7 @@ static IrInstruction *ir_gen_null_literal(IrBuilder *irb, AstNode *node) { | ... | @@ -1498,7 +1498,7 @@ static IrInstruction *ir_gen_null_literal(IrBuilder *irb, AstNode *node) { |
| 1498 | } | 1498 | } |
| 1499 | | 1499 | |
| 1500 | static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstNode *decl_node, | 1500 | static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstNode *decl_node, |
| 1501 | LValPurpose lval, BlockContext *scope) | 1501 | LValPurpose lval, Scope *scope) |
| 1502 | { | 1502 | { |
| 1503 | resolve_top_level_decl(irb->codegen, decl_node, lval != LValPurposeNone); | 1503 | resolve_top_level_decl(irb->codegen, decl_node, lval != LValPurposeNone); |
| 1504 | TopLevelDecl *tld = get_as_top_level_decl(decl_node); | 1504 | TopLevelDecl *tld = get_as_top_level_decl(decl_node); |
| ... | @@ -1565,7 +1565,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, LValPurpose l | ... | @@ -1565,7 +1565,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, LValPurpose l |
| 1565 | } | 1565 | } |
| 1566 | } | 1566 | } |
| 1567 | | 1567 | |
| 1568 | VariableTableEntry *var = find_variable(irb->codegen, node->block_context, variable_name); | 1568 | VariableTableEntry *var = find_variable(irb->codegen, node->scope, variable_name); |
| 1569 | if (var) { | 1569 | if (var) { |
| 1570 | IrInstruction *var_ptr = ir_build_var_ptr(irb, node, var); | 1570 | IrInstruction *var_ptr = ir_build_var_ptr(irb, node, var); |
| 1571 | if (lval != LValPurposeNone) | 1571 | if (lval != LValPurposeNone) |
| ... | @@ -1574,9 +1574,9 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, LValPurpose l | ... | @@ -1574,9 +1574,9 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, LValPurpose l |
| 1574 | return ir_build_load_ptr(irb, node, var_ptr); | 1574 | return ir_build_load_ptr(irb, node, var_ptr); |
| 1575 | } | 1575 | } |
| 1576 | | 1576 | |
| 1577 | AstNode *decl_node = find_decl(node->block_context, variable_name); | 1577 | AstNode *decl_node = find_decl(node->scope, variable_name); |
| 1578 | if (decl_node) | 1578 | if (decl_node) |
| 1579 | return ir_gen_decl_ref(irb, node, decl_node, lval, node->block_context); | 1579 | return ir_gen_decl_ref(irb, node, decl_node, lval, node->scope); |
| 1580 | | 1580 | |
| 1581 | if (node->owner->any_imports_failed) { | 1581 | if (node->owner->any_imports_failed) { |
| 1582 | // skip the error message since we had a failing import in this file | 1582 | // skip the error message since we had a failing import in this file |
| ... | @@ -1592,13 +1592,13 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, AstNode *node, LValPur | ... | @@ -1592,13 +1592,13 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, AstNode *node, LValPur |
| 1592 | assert(node->type == NodeTypeArrayAccessExpr); | 1592 | assert(node->type == NodeTypeArrayAccessExpr); |
| 1593 | | 1593 | |
| 1594 | AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr; | 1594 | AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr; |
| 1595 | IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, node->block_context, | 1595 | IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, node->scope, |
| 1596 | LValPurposeAddressOf); | 1596 | LValPurposeAddressOf); |
| 1597 | if (array_ref_instruction == irb->codegen->invalid_instruction) | 1597 | if (array_ref_instruction == irb->codegen->invalid_instruction) |
| 1598 | return array_ref_instruction; | 1598 | return array_ref_instruction; |
| 1599 | | 1599 | |
| 1600 | AstNode *subscript_node = node->data.array_access_expr.subscript; | 1600 | AstNode *subscript_node = node->data.array_access_expr.subscript; |
| 1601 | IrInstruction *subscript_instruction = ir_gen_node(irb, subscript_node, node->block_context); | 1601 | IrInstruction *subscript_instruction = ir_gen_node(irb, subscript_node, node->scope); |
| 1602 | if (subscript_instruction == irb->codegen->invalid_instruction) | 1602 | if (subscript_instruction == irb->codegen->invalid_instruction) |
| 1603 | return subscript_instruction; | 1603 | return subscript_instruction; |
| 1604 | | 1604 | |
| ... | @@ -1616,7 +1616,7 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, AstNode *node, LValPur | ... | @@ -1616,7 +1616,7 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, AstNode *node, LValPur |
| 1616 | AstNode *container_ref_node = node->data.field_access_expr.struct_expr; | 1616 | AstNode *container_ref_node = node->data.field_access_expr.struct_expr; |
| 1617 | Buf *field_name = node->data.field_access_expr.field_name; | 1617 | Buf *field_name = node->data.field_access_expr.field_name; |
| 1618 | | 1618 | |
| 1619 | IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, node->block_context, | 1619 | IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, node->scope, |
| 1620 | LValPurposeAddressOf); | 1620 | LValPurposeAddressOf); |
| 1621 | if (container_ref_instruction == irb->codegen->invalid_instruction) | 1621 | if (container_ref_instruction == irb->codegen->invalid_instruction) |
| 1622 | return container_ref_instruction; | 1622 | return container_ref_instruction; |
| ... | @@ -1661,7 +1661,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { | ... | @@ -1661,7 +1661,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { |
| 1661 | case BuiltinFnIdTypeof: | 1661 | case BuiltinFnIdTypeof: |
| 1662 | { | 1662 | { |
| 1663 | AstNode *arg_node = node->data.fn_call_expr.params.at(0); | 1663 | AstNode *arg_node = node->data.fn_call_expr.params.at(0); |
| 1664 | IrInstruction *arg = ir_gen_node(irb, arg_node, node->block_context); | 1664 | IrInstruction *arg = ir_gen_node(irb, arg_node, node->scope); |
| 1665 | if (arg == irb->codegen->invalid_instruction) | 1665 | if (arg == irb->codegen->invalid_instruction) |
| 1666 | return arg; | 1666 | return arg; |
| 1667 | return ir_build_typeof(irb, node, arg); | 1667 | return ir_build_typeof(irb, node, arg); |
| ... | @@ -1669,12 +1669,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { | ... | @@ -1669,12 +1669,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { |
| 1669 | case BuiltinFnIdSetFnTest: | 1669 | case BuiltinFnIdSetFnTest: |
| 1670 | { | 1670 | { |
| 1671 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 1671 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 1672 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context); | 1672 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope); |
| 1673 | if (arg0_value == irb->codegen->invalid_instruction) | 1673 | if (arg0_value == irb->codegen->invalid_instruction) |
| 1674 | return arg0_value; | 1674 | return arg0_value; |
| 1675 | | 1675 | |
| 1676 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | 1676 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); |
| 1677 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, node->block_context); | 1677 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, node->scope); |
| 1678 | if (arg1_value == irb->codegen->invalid_instruction) | 1678 | if (arg1_value == irb->codegen->invalid_instruction) |
| 1679 | return arg1_value; | 1679 | return arg1_value; |
| 1680 | | 1680 | |
| ... | @@ -1683,12 +1683,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { | ... | @@ -1683,12 +1683,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { |
| 1683 | case BuiltinFnIdSetFnVisible: | 1683 | case BuiltinFnIdSetFnVisible: |
| 1684 | { | 1684 | { |
| 1685 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 1685 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 1686 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context); | 1686 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope); |
| 1687 | if (arg0_value == irb->codegen->invalid_instruction) | 1687 | if (arg0_value == irb->codegen->invalid_instruction) |
| 1688 | return arg0_value; | 1688 | return arg0_value; |
| 1689 | | 1689 | |
| 1690 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | 1690 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); |
| 1691 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, node->block_context); | 1691 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, node->scope); |
| 1692 | if (arg1_value == irb->codegen->invalid_instruction) | 1692 | if (arg1_value == irb->codegen->invalid_instruction) |
| 1693 | return arg1_value; | 1693 | return arg1_value; |
| 1694 | | 1694 | |
| ... | @@ -1697,12 +1697,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { | ... | @@ -1697,12 +1697,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { |
| 1697 | case BuiltinFnIdSetDebugSafety: | 1697 | case BuiltinFnIdSetDebugSafety: |
| 1698 | { | 1698 | { |
| 1699 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 1699 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 1700 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context); | 1700 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope); |
| 1701 | if (arg0_value == irb->codegen->invalid_instruction) | 1701 | if (arg0_value == irb->codegen->invalid_instruction) |
| 1702 | return arg0_value; | 1702 | return arg0_value; |
| 1703 | | 1703 | |
| 1704 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | 1704 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); |
| 1705 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, node->block_context); | 1705 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, node->scope); |
| 1706 | if (arg1_value == irb->codegen->invalid_instruction) | 1706 | if (arg1_value == irb->codegen->invalid_instruction) |
| 1707 | return arg1_value; | 1707 | return arg1_value; |
| 1708 | | 1708 | |
| ... | @@ -1711,7 +1711,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { | ... | @@ -1711,7 +1711,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { |
| 1711 | case BuiltinFnIdCompileVar: | 1711 | case BuiltinFnIdCompileVar: |
| 1712 | { | 1712 | { |
| 1713 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 1713 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 1714 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context); | 1714 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope); |
| 1715 | if (arg0_value == irb->codegen->invalid_instruction) | 1715 | if (arg0_value == irb->codegen->invalid_instruction) |
| 1716 | return arg0_value; | 1716 | return arg0_value; |
| 1717 | | 1717 | |
| ... | @@ -1720,7 +1720,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { | ... | @@ -1720,7 +1720,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { |
| 1720 | case BuiltinFnIdSizeof: | 1720 | case BuiltinFnIdSizeof: |
| 1721 | { | 1721 | { |
| 1722 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 1722 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 1723 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context); | 1723 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope); |
| 1724 | if (arg0_value == irb->codegen->invalid_instruction) | 1724 | if (arg0_value == irb->codegen->invalid_instruction) |
| 1725 | return arg0_value; | 1725 | return arg0_value; |
| 1726 | | 1726 | |
| ... | @@ -1729,7 +1729,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { | ... | @@ -1729,7 +1729,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { |
| 1729 | case BuiltinFnIdCtz: | 1729 | case BuiltinFnIdCtz: |
| 1730 | { | 1730 | { |
| 1731 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 1731 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 1732 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context); | 1732 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope); |
| 1733 | if (arg0_value == irb->codegen->invalid_instruction) | 1733 | if (arg0_value == irb->codegen->invalid_instruction) |
| 1734 | return arg0_value; | 1734 | return arg0_value; |
| 1735 | | 1735 | |
| ... | @@ -1738,7 +1738,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { | ... | @@ -1738,7 +1738,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { |
| 1738 | case BuiltinFnIdClz: | 1738 | case BuiltinFnIdClz: |
| 1739 | { | 1739 | { |
| 1740 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 1740 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 1741 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context); | 1741 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope); |
| 1742 | if (arg0_value == irb->codegen->invalid_instruction) | 1742 | if (arg0_value == irb->codegen->invalid_instruction) |
| 1743 | return arg0_value; | 1743 | return arg0_value; |
| 1744 | | 1744 | |
| ... | @@ -1747,7 +1747,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { | ... | @@ -1747,7 +1747,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { |
| 1747 | case BuiltinFnIdStaticEval: | 1747 | case BuiltinFnIdStaticEval: |
| 1748 | { | 1748 | { |
| 1749 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 1749 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 1750 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context); | 1750 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope); |
| 1751 | if (arg0_value == irb->codegen->invalid_instruction) | 1751 | if (arg0_value == irb->codegen->invalid_instruction) |
| 1752 | return arg0_value; | 1752 | return arg0_value; |
| 1753 | | 1753 | |
| ... | @@ -1756,11 +1756,11 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { | ... | @@ -1756,11 +1756,11 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { |
| 1756 | case BuiltinFnIdImport: | 1756 | case BuiltinFnIdImport: |
| 1757 | { | 1757 | { |
| 1758 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 1758 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 1759 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context); | 1759 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope); |
| 1760 | if (arg0_value == irb->codegen->invalid_instruction) | 1760 | if (arg0_value == irb->codegen->invalid_instruction) |
| 1761 | return arg0_value; | 1761 | return arg0_value; |
| 1762 | | 1762 | |
| 1763 | if (node->block_context->fn_entry) { | 1763 | if (node->scope->fn_entry) { |
| 1764 | add_node_error(irb->codegen, node, buf_sprintf("import valid only at top level scope")); | 1764 | add_node_error(irb->codegen, node, buf_sprintf("import valid only at top level scope")); |
| 1765 | return irb->codegen->invalid_instruction; | 1765 | return irb->codegen->invalid_instruction; |
| 1766 | } | 1766 | } |
| ... | @@ -1805,7 +1805,7 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, AstNode *node) { | ... | @@ -1805,7 +1805,7 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, AstNode *node) { |
| 1805 | return ir_gen_builtin_fn_call(irb, node); | 1805 | return ir_gen_builtin_fn_call(irb, node); |
| 1806 | | 1806 | |
| 1807 | AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; | 1807 | AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; |
| 1808 | IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, node->block_context); | 1808 | IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, node->scope); |
| 1809 | if (fn_ref == irb->codegen->invalid_instruction) | 1809 | if (fn_ref == irb->codegen->invalid_instruction) |
| 1810 | return fn_ref; | 1810 | return fn_ref; |
| 1811 | | 1811 | |
| ... | @@ -1813,7 +1813,7 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, AstNode *node) { | ... | @@ -1813,7 +1813,7 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, AstNode *node) { |
| 1813 | IrInstruction **args = allocate<IrInstruction*>(arg_count); | 1813 | IrInstruction **args = allocate<IrInstruction*>(arg_count); |
| 1814 | for (size_t i = 0; i < arg_count; i += 1) { | 1814 | for (size_t i = 0; i < arg_count; i += 1) { |
| 1815 | AstNode *arg_node = node->data.fn_call_expr.params.at(i); | 1815 | AstNode *arg_node = node->data.fn_call_expr.params.at(i); |
| 1816 | args[i] = ir_gen_node(irb, arg_node, node->block_context); | 1816 | args[i] = ir_gen_node(irb, arg_node, node->scope); |
| 1817 | } | 1817 | } |
| 1818 | | 1818 | |
| 1819 | return ir_build_call(irb, node, nullptr, fn_ref, arg_count, args); | 1819 | return ir_build_call(irb, node, nullptr, fn_ref, arg_count, args); |
| ... | @@ -1822,7 +1822,7 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, AstNode *node) { | ... | @@ -1822,7 +1822,7 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, AstNode *node) { |
| 1822 | static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) { | 1822 | static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) { |
| 1823 | assert(node->type == NodeTypeIfBoolExpr); | 1823 | assert(node->type == NodeTypeIfBoolExpr); |
| 1824 | | 1824 | |
| 1825 | IrInstruction *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, node->block_context); | 1825 | IrInstruction *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, node->scope); |
| 1826 | if (condition == irb->codegen->invalid_instruction) | 1826 | if (condition == irb->codegen->invalid_instruction) |
| 1827 | return condition; | 1827 | return condition; |
| 1828 | | 1828 | |
| ... | @@ -1837,7 +1837,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -1837,7 +1837,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) { |
| 1837 | ir_build_cond_br(irb, condition->source_node, condition, then_block, else_block, is_inline); | 1837 | ir_build_cond_br(irb, condition->source_node, condition, then_block, else_block, is_inline); |
| 1838 | | 1838 | |
| 1839 | ir_set_cursor_at_end(irb, then_block); | 1839 | ir_set_cursor_at_end(irb, then_block); |
| 1840 | IrInstruction *then_expr_result = ir_gen_node(irb, then_node, node->block_context); | 1840 | IrInstruction *then_expr_result = ir_gen_node(irb, then_node, node->scope); |
| 1841 | if (then_expr_result == irb->codegen->invalid_instruction) | 1841 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 1842 | return then_expr_result; | 1842 | return then_expr_result; |
| 1843 | IrBasicBlock *after_then_block = irb->current_basic_block; | 1843 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| ... | @@ -1846,7 +1846,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -1846,7 +1846,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) { |
| 1846 | ir_set_cursor_at_end(irb, else_block); | 1846 | ir_set_cursor_at_end(irb, else_block); |
| 1847 | IrInstruction *else_expr_result; | 1847 | IrInstruction *else_expr_result; |
| 1848 | if (else_node) { | 1848 | if (else_node) { |
| 1849 | else_expr_result = ir_gen_node(irb, else_node, node->block_context); | 1849 | else_expr_result = ir_gen_node(irb, else_node, node->scope); |
| 1850 | if (else_expr_result == irb->codegen->invalid_instruction) | 1850 | if (else_expr_result == irb->codegen->invalid_instruction) |
| 1851 | return else_expr_result; | 1851 | return else_expr_result; |
| 1852 | } else { | 1852 | } else { |
| ... | @@ -1870,7 +1870,7 @@ static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, AstNode *node, Ir | ... | @@ -1870,7 +1870,7 @@ static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, AstNode *node, Ir |
| 1870 | assert(node->type == NodeTypePrefixOpExpr); | 1870 | assert(node->type == NodeTypePrefixOpExpr); |
| 1871 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; | 1871 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; |
| 1872 | | 1872 | |
| 1873 | IrInstruction *value = ir_gen_node_extra(irb, expr_node, node->block_context, lval); | 1873 | IrInstruction *value = ir_gen_node_extra(irb, expr_node, node->scope, lval); |
| 1874 | if (value == irb->codegen->invalid_instruction) | 1874 | if (value == irb->codegen->invalid_instruction) |
| 1875 | return value; | 1875 | return value; |
| 1876 | | 1876 | |
| ... | @@ -1887,7 +1887,7 @@ static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, AstNode *node, IrUnOp | ... | @@ -1887,7 +1887,7 @@ static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, AstNode *node, IrUnOp |
| 1887 | | 1887 | |
| 1888 | static IrInstruction *ir_gen_prefix_op_unwrap_maybe(IrBuilder *irb, AstNode *node, LValPurpose lval) { | 1888 | static IrInstruction *ir_gen_prefix_op_unwrap_maybe(IrBuilder *irb, AstNode *node, LValPurpose lval) { |
| 1889 | AstNode *expr = node->data.prefix_op_expr.primary_expr; | 1889 | AstNode *expr = node->data.prefix_op_expr.primary_expr; |
| 1890 | IrInstruction *value = ir_gen_node_extra(irb, expr, node->block_context, LValPurposeAddressOf); | 1890 | IrInstruction *value = ir_gen_node_extra(irb, expr, node->scope, LValPurposeAddressOf); |
| 1891 | if (value == irb->codegen->invalid_instruction) | 1891 | if (value == irb->codegen->invalid_instruction) |
| 1892 | return value; | 1892 | return value; |
| 1893 | | 1893 | |
| ... | @@ -1938,7 +1938,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node) | ... | @@ -1938,7 +1938,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node) |
| 1938 | AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr; | 1938 | AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr; |
| 1939 | ContainerInitKind kind = container_init_expr->kind; | 1939 | ContainerInitKind kind = container_init_expr->kind; |
| 1940 | | 1940 | |
| 1941 | IrInstruction *container_type = ir_gen_node(irb, container_init_expr->type, node->block_context); | 1941 | IrInstruction *container_type = ir_gen_node(irb, container_init_expr->type, node->scope); |
| 1942 | if (container_type == irb->codegen->invalid_instruction) | 1942 | if (container_type == irb->codegen->invalid_instruction) |
| 1943 | return container_type; | 1943 | return container_type; |
| 1944 | | 1944 | |
| ... | @@ -1951,7 +1951,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node) | ... | @@ -1951,7 +1951,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node) |
| 1951 | | 1951 | |
| 1952 | Buf *name = entry_node->data.struct_val_field.name; | 1952 | Buf *name = entry_node->data.struct_val_field.name; |
| 1953 | AstNode *expr_node = entry_node->data.struct_val_field.expr; | 1953 | AstNode *expr_node = entry_node->data.struct_val_field.expr; |
| 1954 | IrInstruction *expr_value = ir_gen_node(irb, expr_node, node->block_context); | 1954 | IrInstruction *expr_value = ir_gen_node(irb, expr_node, node->scope); |
| 1955 | if (expr_value == irb->codegen->invalid_instruction) | 1955 | if (expr_value == irb->codegen->invalid_instruction) |
| 1956 | return expr_value; | 1956 | return expr_value; |
| 1957 | | 1957 | |
| ... | @@ -1965,7 +1965,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node) | ... | @@ -1965,7 +1965,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node) |
| 1965 | IrInstruction **values = allocate<IrInstruction *>(item_count); | 1965 | IrInstruction **values = allocate<IrInstruction *>(item_count); |
| 1966 | for (size_t i = 0; i < item_count; i += 1) { | 1966 | for (size_t i = 0; i < item_count; i += 1) { |
| 1967 | AstNode *expr_node = container_init_expr->entries.at(i); | 1967 | AstNode *expr_node = container_init_expr->entries.at(i); |
| 1968 | IrInstruction *expr_value = ir_gen_node(irb, expr_node, node->block_context); | 1968 | IrInstruction *expr_value = ir_gen_node(irb, expr_node, node->scope); |
| 1969 | if (expr_value == irb->codegen->invalid_instruction) | 1969 | if (expr_value == irb->codegen->invalid_instruction) |
| 1970 | return expr_value; | 1970 | return expr_value; |
| 1971 | | 1971 | |
| ... | @@ -1984,14 +1984,14 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) { | ... | @@ -1984,14 +1984,14 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) { |
| 1984 | | 1984 | |
| 1985 | IrInstruction *type_instruction; | 1985 | IrInstruction *type_instruction; |
| 1986 | if (variable_declaration->type != nullptr) { | 1986 | if (variable_declaration->type != nullptr) { |
| 1987 | type_instruction = ir_gen_node(irb, variable_declaration->type, node->block_context); | 1987 | type_instruction = ir_gen_node(irb, variable_declaration->type, node->scope); |
| 1988 | if (type_instruction == irb->codegen->invalid_instruction) | 1988 | if (type_instruction == irb->codegen->invalid_instruction) |
| 1989 | return type_instruction; | 1989 | return type_instruction; |
| 1990 | } else { | 1990 | } else { |
| 1991 | type_instruction = nullptr; | 1991 | type_instruction = nullptr; |
| 1992 | } | 1992 | } |
| 1993 | | 1993 | |
| 1994 | IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, node->block_context); | 1994 | IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, node->scope); |
| 1995 | if (init_value == irb->codegen->invalid_instruction) | 1995 | if (init_value == irb->codegen->invalid_instruction) |
| 1996 | return init_value; | 1996 | return init_value; |
| 1997 | | 1997 | |
| ... | @@ -1999,7 +1999,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) { | ... | @@ -1999,7 +1999,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) { |
| 1999 | bool is_const = variable_declaration->is_const; | 1999 | bool is_const = variable_declaration->is_const; |
| 2000 | bool is_extern = variable_declaration->is_extern; | 2000 | bool is_extern = variable_declaration->is_extern; |
| 2001 | bool is_inline = ir_should_inline(irb) || variable_declaration->is_inline; | 2001 | bool is_inline = ir_should_inline(irb) || variable_declaration->is_inline; |
| 2002 | VariableTableEntry *var = ir_add_local_var(irb, node, node->block_context, | 2002 | VariableTableEntry *var = ir_add_local_var(irb, node, node->scope, |
| 2003 | variable_declaration->symbol, is_const, is_const, is_shadowable, is_inline); | 2003 | variable_declaration->symbol, is_const, is_const, is_shadowable, is_inline); |
| 2004 | | 2004 | |
| 2005 | if (!is_extern && !variable_declaration->expr) { | 2005 | if (!is_extern && !variable_declaration->expr) { |
| ... | @@ -2027,19 +2027,19 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -2027,19 +2027,19 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, AstNode *node) { |
| 2027 | | 2027 | |
| 2028 | if (continue_expr_node) { | 2028 | if (continue_expr_node) { |
| 2029 | ir_set_cursor_at_end(irb, continue_block); | 2029 | ir_set_cursor_at_end(irb, continue_block); |
| 2030 | ir_gen_node(irb, continue_expr_node, node->block_context); | 2030 | ir_gen_node(irb, continue_expr_node, node->scope); |
| 2031 | ir_build_br(irb, node, cond_block, is_inline); | 2031 | ir_build_br(irb, node, cond_block, is_inline); |
| 2032 | } | 2032 | } |
| 2033 | | 2033 | |
| 2034 | ir_set_cursor_at_end(irb, cond_block); | 2034 | ir_set_cursor_at_end(irb, cond_block); |
| 2035 | IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, node->block_context); | 2035 | IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, node->scope); |
| 2036 | ir_build_cond_br(irb, node->data.while_expr.condition, cond_val, body_block, end_block, is_inline); | 2036 | ir_build_cond_br(irb, node->data.while_expr.condition, cond_val, body_block, end_block, is_inline); |
| 2037 | | 2037 | |
| 2038 | ir_set_cursor_at_end(irb, body_block); | 2038 | ir_set_cursor_at_end(irb, body_block); |
| 2039 | | 2039 | |
| 2040 | irb->break_block_stack.append(end_block); | 2040 | irb->break_block_stack.append(end_block); |
| 2041 | irb->continue_block_stack.append(continue_block); | 2041 | irb->continue_block_stack.append(continue_block); |
| 2042 | ir_gen_node(irb, node->data.while_expr.body, node->block_context); | 2042 | ir_gen_node(irb, node->data.while_expr.body, node->scope); |
| 2043 | irb->break_block_stack.pop(); | 2043 | irb->break_block_stack.pop(); |
| 2044 | irb->continue_block_stack.pop(); | 2044 | irb->continue_block_stack.pop(); |
| 2045 | | 2045 | |
| ... | @@ -2052,7 +2052,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -2052,7 +2052,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, AstNode *node) { |
| 2052 | static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) { | 2052 | static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) { |
| 2053 | assert(node->type == NodeTypeForExpr); | 2053 | assert(node->type == NodeTypeForExpr); |
| 2054 | | 2054 | |
| 2055 | BlockContext *parent_scope = node->block_context; | 2055 | Scope *parent_scope = node->scope; |
| 2056 | | 2056 | |
| 2057 | AstNode *array_node = node->data.for_expr.array_expr; | 2057 | AstNode *array_node = node->data.for_expr.array_expr; |
| 2058 | AstNode *elem_node = node->data.for_expr.elem_node; | 2058 | AstNode *elem_node = node->data.for_expr.elem_node; |
| ... | @@ -2079,9 +2079,9 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -2079,9 +2079,9 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) { |
| 2079 | } | 2079 | } |
| 2080 | bool is_inline = ir_should_inline(irb) || node->data.for_expr.is_inline; | 2080 | bool is_inline = ir_should_inline(irb) || node->data.for_expr.is_inline; |
| 2081 | | 2081 | |
| 2082 | BlockContext *child_scope = new_block_context(node, parent_scope); | 2082 | Scope *child_scope = new_scope(node, parent_scope); |
| 2083 | child_scope->parent_loop_node = node; | 2083 | child_scope->parent_loop_node = node; |
| 2084 | elem_node->block_context = child_scope; | 2084 | elem_node->scope = child_scope; |
| 2085 | | 2085 | |
| 2086 | // TODO make it an error to write to element variable or i variable. | 2086 | // TODO make it an error to write to element variable or i variable. |
| 2087 | Buf *elem_var_name = elem_node->data.symbol_expr.symbol; | 2087 | Buf *elem_var_name = elem_node->data.symbol_expr.symbol; |
| ... | @@ -2095,7 +2095,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -2095,7 +2095,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) { |
| 2095 | if (index_node) { | 2095 | if (index_node) { |
| 2096 | index_var_source_node = index_node; | 2096 | index_var_source_node = index_node; |
| 2097 | Buf *index_var_name = index_node->data.symbol_expr.symbol; | 2097 | Buf *index_var_name = index_node->data.symbol_expr.symbol; |
| 2098 | index_node->block_context = child_scope; | 2098 | index_node->scope = child_scope; |
| 2099 | node->data.for_expr.index_var = ir_add_local_var(irb, index_node, child_scope, index_var_name, | 2099 | node->data.for_expr.index_var = ir_add_local_var(irb, index_node, child_scope, index_var_name, |
| 2100 | true, false, false, is_inline); | 2100 | true, false, false, is_inline); |
| 2101 | } else { | 2101 | } else { |
| ... | @@ -2154,7 +2154,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -2154,7 +2154,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) { |
| 2154 | static IrInstruction *ir_gen_this_literal(IrBuilder *irb, AstNode *node) { | 2154 | static IrInstruction *ir_gen_this_literal(IrBuilder *irb, AstNode *node) { |
| 2155 | assert(node->type == NodeTypeThisLiteral); | 2155 | assert(node->type == NodeTypeThisLiteral); |
| 2156 | | 2156 | |
| 2157 | BlockContext *scope = node->block_context; | 2157 | Scope *scope = node->scope; |
| 2158 | | 2158 | |
| 2159 | if (!scope->parent) | 2159 | if (!scope->parent) |
| 2160 | return ir_build_const_import(irb, node, node->owner); | 2160 | return ir_build_const_import(irb, node, node->owner); |
| ... | @@ -2205,18 +2205,18 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, AstNode *node) { | ... | @@ -2205,18 +2205,18 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, AstNode *node) { |
| 2205 | return irb->codegen->invalid_instruction; | 2205 | return irb->codegen->invalid_instruction; |
| 2206 | } | 2206 | } |
| 2207 | | 2207 | |
| 2208 | IrInstruction *size_value = ir_gen_node(irb, size_node, node->block_context); | 2208 | IrInstruction *size_value = ir_gen_node(irb, size_node, node->scope); |
| 2209 | if (size_value == irb->codegen->invalid_instruction) | 2209 | if (size_value == irb->codegen->invalid_instruction) |
| 2210 | return size_value; | 2210 | return size_value; |
| 2211 | | 2211 | |
| 2212 | IrInstruction *child_type = ir_gen_node(irb, child_type_node, node->block_context); | 2212 | IrInstruction *child_type = ir_gen_node(irb, child_type_node, node->scope); |
| 2213 | if (child_type == irb->codegen->invalid_instruction) | 2213 | if (child_type == irb->codegen->invalid_instruction) |
| 2214 | return child_type; | 2214 | return child_type; |
| 2215 | | 2215 | |
| 2216 | return ir_build_array_type(irb, node, size_value, child_type); | 2216 | return ir_build_array_type(irb, node, size_value, child_type); |
| 2217 | } else { | 2217 | } else { |
| 2218 | IrInstruction *child_type = ir_gen_node_extra(irb, child_type_node, | 2218 | IrInstruction *child_type = ir_gen_node_extra(irb, child_type_node, |
| 2219 | node->block_context, LValPurposeAddressOf); | 2219 | node->scope, LValPurposeAddressOf); |
| 2220 | if (child_type == irb->codegen->invalid_instruction) | 2220 | if (child_type == irb->codegen->invalid_instruction) |
| 2221 | return child_type; | 2221 | return child_type; |
| 2222 | | 2222 | |
| ... | @@ -2246,7 +2246,7 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -2246,7 +2246,7 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, AstNode *node) { |
| 2246 | if (asm_output->return_type) { | 2246 | if (asm_output->return_type) { |
| 2247 | return_count += 1; | 2247 | return_count += 1; |
| 2248 | | 2248 | |
| 2249 | IrInstruction *return_type = ir_gen_node(irb, asm_output->return_type, node->block_context); | 2249 | IrInstruction *return_type = ir_gen_node(irb, asm_output->return_type, node->scope); |
| 2250 | if (return_type == irb->codegen->invalid_instruction) | 2250 | if (return_type == irb->codegen->invalid_instruction) |
| 2251 | return irb->codegen->invalid_instruction; | 2251 | return irb->codegen->invalid_instruction; |
| 2252 | if (return_count > 1) { | 2252 | if (return_count > 1) { |
| ... | @@ -2257,7 +2257,7 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -2257,7 +2257,7 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, AstNode *node) { |
| 2257 | output_types[i] = return_type; | 2257 | output_types[i] = return_type; |
| 2258 | } else { | 2258 | } else { |
| 2259 | Buf *variable_name = asm_output->variable_name; | 2259 | Buf *variable_name = asm_output->variable_name; |
| 2260 | VariableTableEntry *var = find_variable(irb->codegen, node->block_context, variable_name); | 2260 | VariableTableEntry *var = find_variable(irb->codegen, node->scope, variable_name); |
| 2261 | if (var) { | 2261 | if (var) { |
| 2262 | asm_output->variable = var; | 2262 | asm_output->variable = var; |
| 2263 | } else { | 2263 | } else { |
| ... | @@ -2269,7 +2269,7 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -2269,7 +2269,7 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, AstNode *node) { |
| 2269 | } | 2269 | } |
| 2270 | for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1) { | 2270 | for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1) { |
| 2271 | AsmInput *asm_input = node->data.asm_expr.input_list.at(i); | 2271 | AsmInput *asm_input = node->data.asm_expr.input_list.at(i); |
| 2272 | IrInstruction *input_value = ir_gen_node(irb, asm_input->expr, node->block_context); | 2272 | IrInstruction *input_value = ir_gen_node(irb, asm_input->expr, node->scope); |
| 2273 | if (input_value == irb->codegen->invalid_instruction) | 2273 | if (input_value == irb->codegen->invalid_instruction) |
| 2274 | return irb->codegen->invalid_instruction; | 2274 | return irb->codegen->invalid_instruction; |
| 2275 | | 2275 | |
| ... | @@ -2288,7 +2288,7 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -2288,7 +2288,7 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, AstNode *node) { |
| 2288 | AstNode *else_node = node->data.if_var_expr.else_node; | 2288 | AstNode *else_node = node->data.if_var_expr.else_node; |
| 2289 | bool var_is_ptr = node->data.if_var_expr.var_is_ptr; | 2289 | bool var_is_ptr = node->data.if_var_expr.var_is_ptr; |
| 2290 | | 2290 | |
| 2291 | IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, node->block_context, LValPurposeAddressOf); | 2291 | IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, node->scope, LValPurposeAddressOf); |
| 2292 | if (expr_value == irb->codegen->invalid_instruction) | 2292 | if (expr_value == irb->codegen->invalid_instruction) |
| 2293 | return expr_value; | 2293 | return expr_value; |
| 2294 | | 2294 | |
| ... | @@ -2304,11 +2304,11 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -2304,11 +2304,11 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, AstNode *node) { |
| 2304 | ir_set_cursor_at_end(irb, then_block); | 2304 | ir_set_cursor_at_end(irb, then_block); |
| 2305 | IrInstruction *var_type = nullptr; | 2305 | IrInstruction *var_type = nullptr; |
| 2306 | if (var_decl->type) { | 2306 | if (var_decl->type) { |
| 2307 | var_type = ir_gen_node(irb, var_decl->type, node->block_context); | 2307 | var_type = ir_gen_node(irb, var_decl->type, node->scope); |
| 2308 | if (var_type == irb->codegen->invalid_instruction) | 2308 | if (var_type == irb->codegen->invalid_instruction) |
| 2309 | return irb->codegen->invalid_instruction; | 2309 | return irb->codegen->invalid_instruction; |
| 2310 | } | 2310 | } |
| 2311 | BlockContext *child_scope = new_block_context(node, node->block_context); | 2311 | Scope *child_scope = new_scope(node, node->scope); |
| 2312 | bool is_shadowable = false; | 2312 | bool is_shadowable = false; |
| 2313 | bool is_const = var_decl->is_const; | 2313 | bool is_const = var_decl->is_const; |
| 2314 | VariableTableEntry *var = ir_add_local_var(irb, node, child_scope, | 2314 | VariableTableEntry *var = ir_add_local_var(irb, node, child_scope, |
| ... | @@ -2325,7 +2325,7 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -2325,7 +2325,7 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, AstNode *node) { |
| 2325 | ir_set_cursor_at_end(irb, else_block); | 2325 | ir_set_cursor_at_end(irb, else_block); |
| 2326 | IrInstruction *else_expr_result; | 2326 | IrInstruction *else_expr_result; |
| 2327 | if (else_node) { | 2327 | if (else_node) { |
| 2328 | else_expr_result = ir_gen_node(irb, else_node, node->block_context); | 2328 | else_expr_result = ir_gen_node(irb, else_node, node->scope); |
| 2329 | if (else_expr_result == irb->codegen->invalid_instruction) | 2329 | if (else_expr_result == irb->codegen->invalid_instruction) |
| 2330 | return else_expr_result; | 2330 | return else_expr_result; |
| 2331 | } else { | 2331 | } else { |
| ... | @@ -2354,13 +2354,13 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, AstNode *switch_node, AstNo | ... | @@ -2354,13 +2354,13 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, AstNode *switch_node, AstNo |
| 2354 | | 2354 | |
| 2355 | AstNode *expr_node = prong_node->data.switch_prong.expr; | 2355 | AstNode *expr_node = prong_node->data.switch_prong.expr; |
| 2356 | AstNode *var_symbol_node = prong_node->data.switch_prong.var_symbol; | 2356 | AstNode *var_symbol_node = prong_node->data.switch_prong.var_symbol; |
| 2357 | BlockContext *child_scope; | 2357 | Scope *child_scope; |
| 2358 | if (var_symbol_node) { | 2358 | if (var_symbol_node) { |
| 2359 | assert(var_symbol_node->type == NodeTypeSymbol); | 2359 | assert(var_symbol_node->type == NodeTypeSymbol); |
| 2360 | Buf *var_name = var_symbol_node->data.symbol_expr.symbol; | 2360 | Buf *var_name = var_symbol_node->data.symbol_expr.symbol; |
| 2361 | bool var_is_ptr = prong_node->data.switch_prong.var_is_ptr; | 2361 | bool var_is_ptr = prong_node->data.switch_prong.var_is_ptr; |
| 2362 | | 2362 | |
| 2363 | child_scope = new_block_context(switch_node, switch_node->block_context); | 2363 | child_scope = new_scope(switch_node, switch_node->scope); |
| 2364 | bool is_shadowable = false; | 2364 | bool is_shadowable = false; |
| 2365 | bool is_const = true; | 2365 | bool is_const = true; |
| 2366 | VariableTableEntry *var = ir_add_local_var(irb, var_symbol_node, child_scope, | 2366 | VariableTableEntry *var = ir_add_local_var(irb, var_symbol_node, child_scope, |
| ... | @@ -2375,7 +2375,7 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, AstNode *switch_node, AstNo | ... | @@ -2375,7 +2375,7 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, AstNode *switch_node, AstNo |
| 2375 | IrInstruction *var_type = nullptr; // infer the type | 2375 | IrInstruction *var_type = nullptr; // infer the type |
| 2376 | ir_build_var_decl(irb, var_symbol_node, var, var_type, var_value); | 2376 | ir_build_var_decl(irb, var_symbol_node, var, var_type, var_value); |
| 2377 | } else { | 2377 | } else { |
| 2378 | child_scope = switch_node->block_context; | 2378 | child_scope = switch_node->scope; |
| 2379 | } | 2379 | } |
| 2380 | | 2380 | |
| 2381 | IrInstruction *expr_result = ir_gen_node(irb, expr_node, child_scope); | 2381 | IrInstruction *expr_result = ir_gen_node(irb, expr_node, child_scope); |
| ... | @@ -2391,7 +2391,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -2391,7 +2391,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) { |
| 2391 | assert(node->type == NodeTypeSwitchExpr); | 2391 | assert(node->type == NodeTypeSwitchExpr); |
| 2392 | | 2392 | |
| 2393 | AstNode *target_node = node->data.switch_expr.expr; | 2393 | AstNode *target_node = node->data.switch_expr.expr; |
| 2394 | IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, node->block_context, LValPurposeAddressOf); | 2394 | IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, node->scope, LValPurposeAddressOf); |
| 2395 | if (target_value_ptr == irb->codegen->invalid_instruction) | 2395 | if (target_value_ptr == irb->codegen->invalid_instruction) |
| 2396 | return target_value_ptr; | 2396 | return target_value_ptr; |
| 2397 | IrInstruction *target_value = ir_build_switch_target(irb, node, target_value_ptr); | 2397 | IrInstruction *target_value = ir_build_switch_target(irb, node, target_value_ptr); |
| ... | @@ -2436,15 +2436,15 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -2436,15 +2436,15 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) { |
| 2436 | AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); | 2436 | AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); |
| 2437 | last_item_node = item_node; | 2437 | last_item_node = item_node; |
| 2438 | if (item_node->type == NodeTypeSwitchRange) { | 2438 | if (item_node->type == NodeTypeSwitchRange) { |
| 2439 | item_node->block_context = node->block_context; | 2439 | item_node->scope = node->scope; |
| 2440 | AstNode *start_node = item_node->data.switch_range.start; | 2440 | AstNode *start_node = item_node->data.switch_range.start; |
| 2441 | AstNode *end_node = item_node->data.switch_range.end; | 2441 | AstNode *end_node = item_node->data.switch_range.end; |
| 2442 | | 2442 | |
| 2443 | IrInstruction *start_value = ir_gen_node(irb, start_node, node->block_context); | 2443 | IrInstruction *start_value = ir_gen_node(irb, start_node, node->scope); |
| 2444 | if (start_value == irb->codegen->invalid_instruction) | 2444 | if (start_value == irb->codegen->invalid_instruction) |
| 2445 | return irb->codegen->invalid_instruction; | 2445 | return irb->codegen->invalid_instruction; |
| 2446 | | 2446 | |
| 2447 | IrInstruction *end_value = ir_gen_node(irb, end_node, node->block_context); | 2447 | IrInstruction *end_value = ir_gen_node(irb, end_node, node->scope); |
| 2448 | if (end_value == irb->codegen->invalid_instruction) | 2448 | if (end_value == irb->codegen->invalid_instruction) |
| 2449 | return irb->codegen->invalid_instruction; | 2449 | return irb->codegen->invalid_instruction; |
| 2450 | | 2450 | |
| ... | @@ -2463,7 +2463,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -2463,7 +2463,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) { |
| 2463 | ok_bit = both_ok; | 2463 | ok_bit = both_ok; |
| 2464 | } | 2464 | } |
| 2465 | } else { | 2465 | } else { |
| 2466 | IrInstruction *item_value = ir_gen_node(irb, item_node, node->block_context); | 2466 | IrInstruction *item_value = ir_gen_node(irb, item_node, node->scope); |
| 2467 | if (item_value == irb->codegen->invalid_instruction) | 2467 | if (item_value == irb->codegen->invalid_instruction) |
| 2468 | return irb->codegen->invalid_instruction; | 2468 | return irb->codegen->invalid_instruction; |
| 2469 | | 2469 | |
| ... | @@ -2500,7 +2500,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -2500,7 +2500,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) { |
| 2500 | AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); | 2500 | AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); |
| 2501 | assert(item_node->type != NodeTypeSwitchRange); | 2501 | assert(item_node->type != NodeTypeSwitchRange); |
| 2502 | | 2502 | |
| 2503 | IrInstruction *item_value = ir_gen_node(irb, item_node, node->block_context); | 2503 | IrInstruction *item_value = ir_gen_node(irb, item_node, node->scope); |
| 2504 | if (item_value == irb->codegen->invalid_instruction) | 2504 | if (item_value == irb->codegen->invalid_instruction) |
| 2505 | return irb->codegen->invalid_instruction; | 2505 | return irb->codegen->invalid_instruction; |
| 2506 | | 2506 | |
| ... | @@ -2542,8 +2542,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -2542,8 +2542,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) { |
| 2542 | return ir_build_phi(irb, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); | 2542 | return ir_build_phi(irb, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 2543 | } | 2543 | } |
| 2544 | | 2544 | |
| 2545 | static LabelTableEntry *find_label(IrExecutable *exec, BlockContext *orig_context, Buf *name) { | 2545 | static LabelTableEntry *find_label(IrExecutable *exec, Scope *orig_context, Buf *name) { |
| 2546 | BlockContext *context = orig_context; | 2546 | Scope *context = orig_context; |
| 2547 | while (context) { | 2547 | while (context) { |
| 2548 | auto entry = context->label_table.maybe_get(name); | 2548 | auto entry = context->label_table.maybe_get(name); |
| 2549 | if (entry) { | 2549 | if (entry) { |
| ... | @@ -2564,14 +2564,14 @@ static IrInstruction *ir_gen_label(IrBuilder *irb, AstNode *node) { | ... | @@ -2564,14 +2564,14 @@ static IrInstruction *ir_gen_label(IrBuilder *irb, AstNode *node) { |
| 2564 | label->bb = label_block; | 2564 | label->bb = label_block; |
| 2565 | irb->exec->all_labels.append(label); | 2565 | irb->exec->all_labels.append(label); |
| 2566 | | 2566 | |
| 2567 | LabelTableEntry *existing_label = find_label(irb->exec, node->block_context, label_name); | 2567 | LabelTableEntry *existing_label = find_label(irb->exec, node->scope, label_name); |
| 2568 | if (existing_label) { | 2568 | if (existing_label) { |
| 2569 | ErrorMsg *msg = add_node_error(irb->codegen, node, | 2569 | ErrorMsg *msg = add_node_error(irb->codegen, node, |
| 2570 | buf_sprintf("duplicate label name '%s'", buf_ptr(label_name))); | 2570 | buf_sprintf("duplicate label name '%s'", buf_ptr(label_name))); |
| 2571 | add_error_note(irb->codegen, msg, existing_label->decl_node, buf_sprintf("other label here")); | 2571 | add_error_note(irb->codegen, msg, existing_label->decl_node, buf_sprintf("other label here")); |
| 2572 | return irb->codegen->invalid_instruction; | 2572 | return irb->codegen->invalid_instruction; |
| 2573 | } else { | 2573 | } else { |
| 2574 | node->block_context->label_table.put(label_name, label); | 2574 | node->scope->label_table.put(label_name, label); |
| 2575 | } | 2575 | } |
| 2576 | | 2576 | |
| 2577 | bool is_inline = ir_should_inline(irb); | 2577 | bool is_inline = ir_should_inline(irb); |
| ... | @@ -2607,11 +2607,11 @@ static IrInstruction *ir_gen_type_literal(IrBuilder *irb, AstNode *node) { | ... | @@ -2607,11 +2607,11 @@ static IrInstruction *ir_gen_type_literal(IrBuilder *irb, AstNode *node) { |
| 2607 | return ir_build_const_type(irb, node, irb->codegen->builtin_types.entry_type); | 2607 | return ir_build_const_type(irb, node, irb->codegen->builtin_types.entry_type); |
| 2608 | } | 2608 | } |
| 2609 | | 2609 | |
| 2610 | static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, BlockContext *block_context, | 2610 | static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope, |
| 2611 | LValPurpose lval) | 2611 | LValPurpose lval) |
| 2612 | { | 2612 | { |
| 2613 | assert(block_context); | 2613 | assert(scope); |
| 2614 | node->block_context = block_context; | 2614 | node->scope = scope; |
| 2615 | | 2615 | |
| 2616 | switch (node->type) { | 2616 | switch (node->type) { |
| 2617 | case NodeTypeStructValueField: | 2617 | case NodeTypeStructValueField: |
| ... | @@ -2694,15 +2694,15 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, BlockContex | ... | @@ -2694,15 +2694,15 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, BlockContex |
| 2694 | zig_unreachable(); | 2694 | zig_unreachable(); |
| 2695 | } | 2695 | } |
| 2696 | | 2696 | |
| 2697 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockContext *block_context, | 2697 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, |
| 2698 | LValPurpose lval) | 2698 | LValPurpose lval) |
| 2699 | { | 2699 | { |
| 2700 | IrInstruction *result = ir_gen_node_raw(irb, node, block_context, lval); | 2700 | IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval); |
| 2701 | irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction); | 2701 | irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction); |
| 2702 | return result; | 2702 | return result; |
| 2703 | } | 2703 | } |
| 2704 | | 2704 | |
| 2705 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *scope) { | 2705 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) { |
| 2706 | return ir_gen_node_extra(irb, node, scope, LValPurposeNone); | 2706 | return ir_gen_node_extra(irb, node, scope, LValPurposeNone); |
| 2707 | } | 2707 | } |
| 2708 | | 2708 | |
| ... | @@ -2714,7 +2714,7 @@ static bool ir_goto_pass2(IrBuilder *irb) { | ... | @@ -2714,7 +2714,7 @@ static bool ir_goto_pass2(IrBuilder *irb) { |
| 2714 | IrInstruction *old_instruction = *slot; | 2714 | IrInstruction *old_instruction = *slot; |
| 2715 | | 2715 | |
| 2716 | Buf *label_name = goto_node->data.goto_expr.name; | 2716 | Buf *label_name = goto_node->data.goto_expr.name; |
| 2717 | LabelTableEntry *label = find_label(irb->exec, goto_node->block_context, label_name); | 2717 | LabelTableEntry *label = find_label(irb->exec, goto_node->scope, label_name); |
| 2718 | if (!label) { | 2718 | if (!label) { |
| 2719 | add_node_error(irb->codegen, goto_node, | 2719 | add_node_error(irb->codegen, goto_node, |
| 2720 | buf_sprintf("no label in scope named '%s'", buf_ptr(label_name))); | 2720 | buf_sprintf("no label in scope named '%s'", buf_ptr(label_name))); |
| ... | @@ -2741,7 +2741,7 @@ static bool ir_goto_pass2(IrBuilder *irb) { | ... | @@ -2741,7 +2741,7 @@ static bool ir_goto_pass2(IrBuilder *irb) { |
| 2741 | return true; | 2741 | return true; |
| 2742 | } | 2742 | } |
| 2743 | | 2743 | |
| 2744 | IrInstruction *ir_gen(CodeGen *codegen, AstNode *node, BlockContext *scope, IrExecutable *ir_executable) { | 2744 | IrInstruction *ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_executable) { |
| 2745 | assert(node->owner); | 2745 | assert(node->owner); |
| 2746 | | 2746 | |
| 2747 | IrBuilder ir_builder = {0}; | 2747 | IrBuilder ir_builder = {0}; |
| ... | @@ -2778,7 +2778,7 @@ IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) { | ... | @@ -2778,7 +2778,7 @@ IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) { |
| 2778 | assert(fn_def_node->type == NodeTypeFnDef); | 2778 | assert(fn_def_node->type == NodeTypeFnDef); |
| 2779 | | 2779 | |
| 2780 | AstNode *body_node = fn_def_node->data.fn_def.body; | 2780 | AstNode *body_node = fn_def_node->data.fn_def.body; |
| 2781 | BlockContext *scope = fn_def_node->data.fn_def.block_context; | 2781 | Scope *scope = fn_def_node->data.fn_def.scope; |
| 2782 | | 2782 | |
| 2783 | return ir_gen(codegn, body_node, scope, ir_executable); | 2783 | return ir_gen(codegn, body_node, scope, ir_executable); |
| 2784 | } | 2784 | } |
| ... | @@ -3023,8 +3023,8 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -3023,8 +3023,8 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 3023 | } else { | 3023 | } else { |
| 3024 | IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->source_node, wanted_type, value, cast_op); | 3024 | IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->source_node, wanted_type, value, cast_op); |
| 3025 | result->type_entry = wanted_type; | 3025 | result->type_entry = wanted_type; |
| 3026 | if (need_alloca && source_instr->source_node->block_context->fn_entry) { | 3026 | if (need_alloca && source_instr->source_node->scope->fn_entry) { |
| 3027 | source_instr->source_node->block_context->fn_entry->alloca_list.append(result); | 3027 | source_instr->source_node->scope->fn_entry->alloca_list.append(result); |
| 3028 | } | 3028 | } |
| 3029 | return result; | 3029 | return result; |
| 3030 | } | 3030 | } |
| ... | @@ -3550,7 +3550,7 @@ static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -3550,7 +3550,7 @@ static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_inst |
| 3550 | ir_link_new_instruction(value, source_instruction); | 3550 | ir_link_new_instruction(value, source_instruction); |
| 3551 | return ptr_type; | 3551 | return ptr_type; |
| 3552 | } else { | 3552 | } else { |
| 3553 | FnTableEntry *fn_entry = source_instruction->source_node->block_context->fn_entry; | 3553 | FnTableEntry *fn_entry = source_instruction->source_node->scope->fn_entry; |
| 3554 | IrInstruction *new_instruction = ir_build_ref_from(&ira->new_irb, source_instruction, value); | 3554 | IrInstruction *new_instruction = ir_build_ref_from(&ira->new_irb, source_instruction, value); |
| 3555 | fn_entry->alloca_list.append(new_instruction); | 3555 | fn_entry->alloca_list.append(new_instruction); |
| 3556 | return ptr_type; | 3556 | return ptr_type; |
| ... | @@ -4097,7 +4097,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc | ... | @@ -4097,7 +4097,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 4097 | | 4097 | |
| 4098 | ir_build_var_decl_from(&ira->new_irb, &decl_var_instruction->base, var, var_type, casted_init_value); | 4098 | ir_build_var_decl_from(&ira->new_irb, &decl_var_instruction->base, var, var_type, casted_init_value); |
| 4099 | | 4099 | |
| 4100 | BlockContext *scope = decl_var_instruction->base.source_node->block_context; | 4100 | Scope *scope = decl_var_instruction->base.source_node->scope; |
| 4101 | if (scope->fn_entry) | 4101 | if (scope->fn_entry) |
| 4102 | scope->fn_entry->variable_list.append(var); | 4102 | scope->fn_entry->variable_list.append(var); |
| 4103 | | 4103 | |
| ... | @@ -4201,7 +4201,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal | ... | @@ -4201,7 +4201,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 4201 | fn_entry, fn_ref, call_param_count, casted_args); | 4201 | fn_entry, fn_ref, call_param_count, casted_args); |
| 4202 | | 4202 | |
| 4203 | if (type_has_bits(return_type) && handle_is_ptr(return_type)) | 4203 | if (type_has_bits(return_type) && handle_is_ptr(return_type)) |
| 4204 | call_instruction->base.source_node->block_context->fn_entry->alloca_list.append(new_call_instruction); | 4204 | call_instruction->base.source_node->scope->fn_entry->alloca_list.append(new_call_instruction); |
| 4205 | | 4205 | |
| 4206 | return ir_finish_anal(ira, return_type); | 4206 | return ir_finish_anal(ira, return_type); |
| 4207 | } | 4207 | } |
| ... | @@ -4732,7 +4732,7 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc | ... | @@ -4732,7 +4732,7 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc |
| 4732 | return var->type; | 4732 | return var->type; |
| 4733 | | 4733 | |
| 4734 | ConstExprValue *mem_slot = nullptr; | 4734 | ConstExprValue *mem_slot = nullptr; |
| 4735 | if (var->block_context->fn_entry) { | 4735 | if (var->scope->fn_entry) { |
| 4736 | // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing. | 4736 | // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing. |
| 4737 | if (var->mem_slot_index != SIZE_MAX) | 4737 | if (var->mem_slot_index != SIZE_MAX) |
| 4738 | mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index]; | 4738 | mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index]; |
| ... | @@ -4879,7 +4879,7 @@ static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira, | ... | @@ -4879,7 +4879,7 @@ static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira, |
| 4879 | IrInstruction *container_ptr, TypeTableEntry *container_type) | 4879 | IrInstruction *container_ptr, TypeTableEntry *container_type) |
| 4880 | { | 4880 | { |
| 4881 | if (!is_slice(bare_struct_type)) { | 4881 | if (!is_slice(bare_struct_type)) { |
| 4882 | BlockContext *container_block_context = get_container_block_context(bare_struct_type); | 4882 | Scope *container_block_context = get_container_block_context(bare_struct_type); |
| 4883 | assert(container_block_context); | 4883 | assert(container_block_context); |
| 4884 | auto entry = container_block_context->decl_table.maybe_get(field_name); | 4884 | auto entry = container_block_context->decl_table.maybe_get(field_name); |
| 4885 | AstNode *fn_decl_node = entry ? entry->value : nullptr; | 4885 | AstNode *fn_decl_node = entry ? entry->value : nullptr; |
| ... | @@ -5023,7 +5023,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru | ... | @@ -5023,7 +5023,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 5023 | } else if (child_type->id == TypeTableEntryIdEnum) { | 5023 | } else if (child_type->id == TypeTableEntryIdEnum) { |
| 5024 | zig_panic("TODO enum type field"); | 5024 | zig_panic("TODO enum type field"); |
| 5025 | } else if (child_type->id == TypeTableEntryIdStruct) { | 5025 | } else if (child_type->id == TypeTableEntryIdStruct) { |
| 5026 | BlockContext *container_block_context = get_container_block_context(child_type); | 5026 | Scope *container_block_context = get_container_block_context(child_type); |
| 5027 | auto entry = container_block_context->decl_table.maybe_get(field_name); | 5027 | auto entry = container_block_context->decl_table.maybe_get(field_name); |
| 5028 | AstNode *decl_node = entry ? entry->value : nullptr; | 5028 | AstNode *decl_node = entry ? entry->value : nullptr; |
| 5029 | if (decl_node) { | 5029 | if (decl_node) { |
| ... | @@ -5055,7 +5055,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru | ... | @@ -5055,7 +5055,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 5055 | ImportTableEntry *namespace_import = namespace_val->data.x_import; | 5055 | ImportTableEntry *namespace_import = namespace_val->data.x_import; |
| 5056 | | 5056 | |
| 5057 | bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var; | 5057 | bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var; |
| 5058 | AstNode *decl_node = find_decl(namespace_import->block_context, field_name); | 5058 | AstNode *decl_node = find_decl(namespace_import->scope, field_name); |
| 5059 | if (!decl_node) { | 5059 | if (!decl_node) { |
| 5060 | // we must now resolve all the use decls | 5060 | // we must now resolve all the use decls |
| 5061 | for (size_t i = 0; i < namespace_import->use_decls.length; i += 1) { | 5061 | for (size_t i = 0; i < namespace_import->use_decls.length; i += 1) { |
| ... | @@ -5066,7 +5066,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru | ... | @@ -5066,7 +5066,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 5066 | } | 5066 | } |
| 5067 | resolve_use_decl(ira->codegen, use_decl_node); | 5067 | resolve_use_decl(ira->codegen, use_decl_node); |
| 5068 | } | 5068 | } |
| 5069 | decl_node = find_decl(namespace_import->block_context, field_name); | 5069 | decl_node = find_decl(namespace_import->scope, field_name); |
| 5070 | } | 5070 | } |
| 5071 | if (decl_node) { | 5071 | if (decl_node) { |
| 5072 | TopLevelDecl *tld = get_as_top_level_decl(decl_node); | 5072 | TopLevelDecl *tld = get_as_top_level_decl(decl_node); |
| ... | @@ -5323,19 +5323,19 @@ static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira, | ... | @@ -5323,19 +5323,19 @@ static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira, |
| 5323 | if (!target_val) | 5323 | if (!target_val) |
| 5324 | return ira->codegen->builtin_types.entry_invalid; | 5324 | return ira->codegen->builtin_types.entry_invalid; |
| 5325 | | 5325 | |
| 5326 | BlockContext *target_context; | 5326 | Scope *target_context; |
| 5327 | if (target_type->id == TypeTableEntryIdBlock) { | 5327 | if (target_type->id == TypeTableEntryIdBlock) { |
| 5328 | target_context = target_val->data.x_block; | 5328 | target_context = target_val->data.x_block; |
| 5329 | } else if (target_type->id == TypeTableEntryIdFn) { | 5329 | } else if (target_type->id == TypeTableEntryIdFn) { |
| 5330 | target_context = target_val->data.x_fn->fn_def_node->data.fn_def.block_context; | 5330 | target_context = target_val->data.x_fn->fn_def_node->data.fn_def.scope; |
| 5331 | } else if (target_type->id == TypeTableEntryIdMetaType) { | 5331 | } else if (target_type->id == TypeTableEntryIdMetaType) { |
| 5332 | TypeTableEntry *type_arg = target_val->data.x_type; | 5332 | TypeTableEntry *type_arg = target_val->data.x_type; |
| 5333 | if (type_arg->id == TypeTableEntryIdStruct) { | 5333 | if (type_arg->id == TypeTableEntryIdStruct) { |
| 5334 | target_context = type_arg->data.structure.block_context; | 5334 | target_context = type_arg->data.structure.scope; |
| 5335 | } else if (type_arg->id == TypeTableEntryIdEnum) { | 5335 | } else if (type_arg->id == TypeTableEntryIdEnum) { |
| 5336 | target_context = type_arg->data.enumeration.block_context; | 5336 | target_context = type_arg->data.enumeration.scope; |
| 5337 | } else if (type_arg->id == TypeTableEntryIdUnion) { | 5337 | } else if (type_arg->id == TypeTableEntryIdUnion) { |
| 5338 | target_context = type_arg->data.unionation.block_context; | 5338 | target_context = type_arg->data.unionation.scope; |
| 5339 | } else { | 5339 | } else { |
| 5340 | add_node_error(ira->codegen, target_instruction->source_node, | 5340 | add_node_error(ira->codegen, target_instruction->source_node, |
| 5341 | buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&type_arg->name))); | 5341 | buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&type_arg->name))); |
| ... | @@ -5966,7 +5966,7 @@ static TypeTableEntry *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructi | ... | @@ -5966,7 +5966,7 @@ static TypeTableEntry *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructi |
| 5966 | ImportTableEntry *target_import = add_source_file(ira->codegen, target_package, | 5966 | ImportTableEntry *target_import = add_source_file(ira->codegen, target_package, |
| 5967 | abs_full_path, search_dir, import_target_path, import_code); | 5967 | abs_full_path, search_dir, import_target_path, import_code); |
| 5968 | | 5968 | |
| 5969 | scan_decls(ira->codegen, target_import, target_import->block_context, target_import->root); | 5969 | scan_decls(ira->codegen, target_import, target_import->scope, target_import->root); |
| 5970 | | 5970 | |
| 5971 | ConstExprValue *out_val = ir_build_const_from(ira, &import_instruction->base, depends_on_compile_var); | 5971 | ConstExprValue *out_val = ir_build_const_from(ira, &import_instruction->base, depends_on_compile_var); |
| 5972 | out_val->data.x_import = target_import; | 5972 | out_val->data.x_import = target_import; |
| ... | @@ -6021,7 +6021,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru | ... | @@ -6021,7 +6021,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru |
| 6021 | | 6021 | |
| 6022 | IrInstructionStructInitField *new_fields = allocate<IrInstructionStructInitField>(actual_field_count); | 6022 | IrInstructionStructInitField *new_fields = allocate<IrInstructionStructInitField>(actual_field_count); |
| 6023 | | 6023 | |
| 6024 | FnTableEntry *fn_entry = instruction->source_node->block_context->fn_entry; | 6024 | FnTableEntry *fn_entry = instruction->source_node->scope->fn_entry; |
| 6025 | bool outside_fn = (fn_entry == nullptr); | 6025 | bool outside_fn = (fn_entry == nullptr); |
| 6026 | | 6026 | |
| 6027 | ConstExprValue const_val = {}; | 6027 | ConstExprValue const_val = {}; |
| ... | @@ -6124,7 +6124,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira | ... | @@ -6124,7 +6124,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira |
| 6124 | const_val.data.x_array.elements = allocate<ConstExprValue>(elem_count); | 6124 | const_val.data.x_array.elements = allocate<ConstExprValue>(elem_count); |
| 6125 | const_val.data.x_array.size = elem_count; | 6125 | const_val.data.x_array.size = elem_count; |
| 6126 | | 6126 | |
| 6127 | FnTableEntry *fn_entry = instruction->base.source_node->block_context->fn_entry; | 6127 | FnTableEntry *fn_entry = instruction->base.source_node->scope->fn_entry; |
| 6128 | bool outside_fn = (fn_entry == nullptr); | 6128 | bool outside_fn = (fn_entry == nullptr); |
| 6129 | | 6129 | |
| 6130 | IrInstruction **new_items = allocate<IrInstruction *>(elem_count); | 6130 | IrInstruction **new_items = allocate<IrInstruction *>(elem_count); |