| ... | @@ -419,6 +419,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchVar *) { | ... | @@ -419,6 +419,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchVar *) { |
| 419 | return IrInstructionIdSwitchVar; | 419 | return IrInstructionIdSwitchVar; |
| 420 | } | 420 | } |
| 421 | | 421 | |
| | 422 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchElseVar *) { |
| | 423 | return IrInstructionIdSwitchElseVar; |
| | 424 | } |
| | 425 | |
| 422 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchTarget *) { | 426 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchTarget *) { |
| 423 | return IrInstructionIdSwitchTarget; | 427 | return IrInstructionIdSwitchTarget; |
| 424 | } | 428 | } |
| ... | @@ -1791,7 +1795,7 @@ static IrInstruction *ir_build_pop_count(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -1791,7 +1795,7 @@ static IrInstruction *ir_build_pop_count(IrBuilder *irb, Scope *scope, AstNode * |
| 1791 | return &instruction->base; | 1795 | return &instruction->base; |
| 1792 | } | 1796 | } |
| 1793 | | 1797 | |
| 1794 | static IrInstruction *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target_value, | 1798 | static IrInstructionSwitchBr *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target_value, |
| 1795 | IrBasicBlock *else_block, size_t case_count, IrInstructionSwitchBrCase *cases, IrInstruction *is_comptime, | 1799 | IrBasicBlock *else_block, size_t case_count, IrInstructionSwitchBrCase *cases, IrInstruction *is_comptime, |
| 1796 | IrInstruction *switch_prongs_void) | 1800 | IrInstruction *switch_prongs_void) |
| 1797 | { | 1801 | { |
| ... | @@ -1815,7 +1819,7 @@ static IrInstruction *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -1815,7 +1819,7 @@ static IrInstruction *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode * |
| 1815 | ir_ref_bb(cases[i].block); | 1819 | ir_ref_bb(cases[i].block); |
| 1816 | } | 1820 | } |
| 1817 | | 1821 | |
| 1818 | return &instruction->base; | 1822 | return instruction; |
| 1819 | } | 1823 | } |
| 1820 | | 1824 | |
| 1821 | static IrInstruction *ir_build_switch_target(IrBuilder *irb, Scope *scope, AstNode *source_node, | 1825 | static IrInstruction *ir_build_switch_target(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| ... | @@ -1842,6 +1846,18 @@ static IrInstruction *ir_build_switch_var(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -1842,6 +1846,18 @@ static IrInstruction *ir_build_switch_var(IrBuilder *irb, Scope *scope, AstNode |
| 1842 | return &instruction->base; | 1846 | return &instruction->base; |
| 1843 | } | 1847 | } |
| 1844 | | 1848 | |
| | 1849 | // For this instruction the switch_br must be set later. |
| | 1850 | static IrInstructionSwitchElseVar *ir_build_switch_else_var(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 1851 | IrInstruction *target_value_ptr) |
| | 1852 | { |
| | 1853 | IrInstructionSwitchElseVar *instruction = ir_build_instruction<IrInstructionSwitchElseVar>(irb, scope, source_node); |
| | 1854 | instruction->target_value_ptr = target_value_ptr; |
| | 1855 | |
| | 1856 | ir_ref_instruction(target_value_ptr, irb->current_basic_block); |
| | 1857 | |
| | 1858 | return instruction; |
| | 1859 | } |
| | 1860 | |
| 1845 | static IrInstruction *ir_build_union_tag(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { | 1861 | static IrInstruction *ir_build_union_tag(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { |
| 1846 | IrInstructionUnionTag *instruction = ir_build_instruction<IrInstructionUnionTag>(irb, scope, source_node); | 1862 | IrInstructionUnionTag *instruction = ir_build_instruction<IrInstructionUnionTag>(irb, scope, source_node); |
| 1847 | instruction->value = value; | 1863 | instruction->value = value; |
| ... | @@ -6294,7 +6310,8 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6294,7 +6310,8 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6294 | static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node, | 6310 | static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node, |
| 6295 | IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *var_is_comptime, | 6311 | IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *var_is_comptime, |
| 6296 | IrInstruction *target_value_ptr, IrInstruction *prong_value, | 6312 | IrInstruction *target_value_ptr, IrInstruction *prong_value, |
| 6297 | ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values) | 6313 | ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values, |
| | 6314 | IrInstructionSwitchElseVar **out_switch_else_var) |
| 6298 | { | 6315 | { |
| 6299 | assert(switch_node->type == NodeTypeSwitchExpr); | 6316 | assert(switch_node->type == NodeTypeSwitchExpr); |
| 6300 | assert(prong_node->type == NodeTypeSwitchProng); | 6317 | assert(prong_node->type == NodeTypeSwitchProng); |
| ... | @@ -6312,13 +6329,17 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit | ... | @@ -6312,13 +6329,17 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit |
| 6312 | ZigVar *var = ir_create_var(irb, var_symbol_node, scope, | 6329 | ZigVar *var = ir_create_var(irb, var_symbol_node, scope, |
| 6313 | var_name, is_const, is_const, is_shadowable, var_is_comptime); | 6330 | var_name, is_const, is_const, is_shadowable, var_is_comptime); |
| 6314 | child_scope = var->child_scope; | 6331 | child_scope = var->child_scope; |
| 6315 | IrInstruction *var_value; | 6332 | IrInstruction *var_ptr_value; |
| 6316 | if (prong_value) { | 6333 | if (prong_value != nullptr) { |
| 6317 | IrInstruction *var_ptr_value = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr, prong_value); | 6334 | var_ptr_value = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr, prong_value); |
| 6318 | var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, var_symbol_node, var_ptr_value); | | |
| 6319 | } else { | 6335 | } else { |
| 6320 | var_value = var_is_ptr ? target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, target_value_ptr); | 6336 | IrInstructionSwitchElseVar *switch_else_var = ir_build_switch_else_var(irb, scope, var_symbol_node, |
| | 6337 | target_value_ptr); |
| | 6338 | *out_switch_else_var = switch_else_var; |
| | 6339 | var_ptr_value = &switch_else_var->base; |
| 6321 | } | 6340 | } |
| | 6341 | IrInstruction *var_value = var_is_ptr ? |
| | 6342 | var_ptr_value : ir_build_load_ptr(irb, scope, var_symbol_node, var_ptr_value); |
| 6322 | IrInstruction *var_type = nullptr; // infer the type | 6343 | IrInstruction *var_type = nullptr; // infer the type |
| 6323 | ir_build_var_decl_src(irb, scope, var_symbol_node, var, var_type, nullptr, var_value); | 6344 | ir_build_var_decl_src(irb, scope, var_symbol_node, var, var_type, nullptr, var_value); |
| 6324 | } else { | 6345 | } else { |
| ... | @@ -6364,6 +6385,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6364,6 +6385,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6364 | ZigList<IrBasicBlock *> incoming_blocks = {0}; | 6385 | ZigList<IrBasicBlock *> incoming_blocks = {0}; |
| 6365 | ZigList<IrInstructionCheckSwitchProngsRange> check_ranges = {0}; | 6386 | ZigList<IrInstructionCheckSwitchProngsRange> check_ranges = {0}; |
| 6366 | | 6387 | |
| | 6388 | IrInstructionSwitchElseVar *switch_else_var = nullptr; |
| | 6389 | |
| 6367 | // First do the else and the ranges | 6390 | // First do the else and the ranges |
| 6368 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); | 6391 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| 6369 | Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); | 6392 | Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); |
| ... | @@ -6384,7 +6407,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6384,7 +6407,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6384 | IrBasicBlock *prev_block = irb->current_basic_block; | 6407 | IrBasicBlock *prev_block = irb->current_basic_block; |
| 6385 | ir_set_cursor_at_end_and_append_block(irb, else_block); | 6408 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6386 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, | 6409 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 6387 | is_comptime, var_is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values)) | 6410 | is_comptime, var_is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values, |
| | 6411 | &switch_else_var)) |
| 6388 | { | 6412 | { |
| 6389 | return irb->codegen->invalid_instruction; | 6413 | return irb->codegen->invalid_instruction; |
| 6390 | } | 6414 | } |
| ... | @@ -6451,7 +6475,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6451,7 +6475,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6451 | | 6475 | |
| 6452 | ir_set_cursor_at_end_and_append_block(irb, range_block_yes); | 6476 | ir_set_cursor_at_end_and_append_block(irb, range_block_yes); |
| 6453 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, | 6477 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 6454 | is_comptime, var_is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values)) | 6478 | is_comptime, var_is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values, nullptr)) |
| 6455 | { | 6479 | { |
| 6456 | return irb->codegen->invalid_instruction; | 6480 | return irb->codegen->invalid_instruction; |
| 6457 | } | 6481 | } |
| ... | @@ -6495,7 +6519,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6495,7 +6519,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6495 | IrBasicBlock *prev_block = irb->current_basic_block; | 6519 | IrBasicBlock *prev_block = irb->current_basic_block; |
| 6496 | ir_set_cursor_at_end_and_append_block(irb, prong_block); | 6520 | ir_set_cursor_at_end_and_append_block(irb, prong_block); |
| 6497 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, | 6521 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 6498 | is_comptime, var_is_comptime, target_value_ptr, only_item_value, &incoming_blocks, &incoming_values)) | 6522 | is_comptime, var_is_comptime, target_value_ptr, only_item_value, &incoming_blocks, &incoming_values, |
| | 6523 | nullptr)) |
| 6499 | { | 6524 | { |
| 6500 | return irb->codegen->invalid_instruction; | 6525 | return irb->codegen->invalid_instruction; |
| 6501 | } | 6526 | } |
| ... | @@ -6510,7 +6535,11 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6510,7 +6535,11 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6510 | if (cases.length == 0) { | 6535 | if (cases.length == 0) { |
| 6511 | ir_build_br(irb, scope, node, else_block, is_comptime); | 6536 | ir_build_br(irb, scope, node, else_block, is_comptime); |
| 6512 | } else { | 6537 | } else { |
| 6513 | ir_build_switch_br(irb, scope, node, target_value, else_block, cases.length, cases.items, is_comptime, switch_prongs_void); | 6538 | IrInstructionSwitchBr *switch_br = ir_build_switch_br(irb, scope, node, target_value, else_block, |
| | 6539 | cases.length, cases.items, is_comptime, switch_prongs_void); |
| | 6540 | if (switch_else_var != nullptr) { |
| | 6541 | switch_else_var->switch_br = switch_br; |
| | 6542 | } |
| 6514 | } | 6543 | } |
| 6515 | | 6544 | |
| 6516 | if (!else_prong) { | 6545 | if (!else_prong) { |
| ... | @@ -7474,8 +7503,9 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod | ... | @@ -7474,8 +7503,9 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod |
| 7474 | cases[0].block = resume_block; | 7503 | cases[0].block = resume_block; |
| 7475 | cases[1].value = ir_mark_gen(ir_build_const_u8(irb, parent_scope, node, 1)); | 7504 | cases[1].value = ir_mark_gen(ir_build_const_u8(irb, parent_scope, node, 1)); |
| 7476 | cases[1].block = canceled_block; | 7505 | cases[1].block = canceled_block; |
| 7477 | ir_mark_gen(ir_build_switch_br(irb, parent_scope, node, suspend_code, irb->exec->coro_suspend_block, | 7506 | IrInstructionSwitchBr *switch_br = ir_build_switch_br(irb, parent_scope, node, suspend_code, |
| 7478 | 2, cases, const_bool_false, nullptr)); | 7507 | irb->exec->coro_suspend_block, 2, cases, const_bool_false, nullptr); |
| | 7508 | ir_mark_gen(&switch_br->base); |
| 7479 | | 7509 | |
| 7480 | ir_set_cursor_at_end_and_append_block(irb, cleanup_block); | 7510 | ir_set_cursor_at_end_and_append_block(irb, cleanup_block); |
| 7481 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); | 7511 | IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); |
| ... | @@ -8972,6 +9002,15 @@ static bool slice_is_const(ZigType *type) { | ... | @@ -8972,6 +9002,15 @@ static bool slice_is_const(ZigType *type) { |
| 8972 | return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; | 9002 | return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; |
| 8973 | } | 9003 | } |
| 8974 | | 9004 | |
| | 9005 | static void populate_error_set_table(ErrorTableEntry **errors, ZigType *set) { |
| | 9006 | assert(set->id == ZigTypeIdErrorSet); |
| | 9007 | for (uint32_t i = 0; i < set->data.error_set.err_count; i += 1) { |
| | 9008 | ErrorTableEntry *error_entry = set->data.error_set.errors[i]; |
| | 9009 | assert(errors[error_entry->value] == nullptr); |
| | 9010 | errors[error_entry->value] = error_entry; |
| | 9011 | } |
| | 9012 | } |
| | 9013 | |
| 8975 | static ZigType *get_error_set_intersection(IrAnalyze *ira, ZigType *set1, ZigType *set2, | 9014 | static ZigType *get_error_set_intersection(IrAnalyze *ira, ZigType *set1, ZigType *set2, |
| 8976 | AstNode *source_node) | 9015 | AstNode *source_node) |
| 8977 | { | 9016 | { |
| ... | @@ -8991,11 +9030,7 @@ static ZigType *get_error_set_intersection(IrAnalyze *ira, ZigType *set1, ZigTyp | ... | @@ -8991,11 +9030,7 @@ static ZigType *get_error_set_intersection(IrAnalyze *ira, ZigType *set1, ZigTyp |
| 8991 | return set1; | 9030 | return set1; |
| 8992 | } | 9031 | } |
| 8993 | ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); | 9032 | ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); |
| 8994 | for (uint32_t i = 0; i < set1->data.error_set.err_count; i += 1) { | 9033 | populate_error_set_table(errors, set1); |
| 8995 | ErrorTableEntry *error_entry = set1->data.error_set.errors[i]; | | |
| 8996 | assert(errors[error_entry->value] == nullptr); | | |
| 8997 | errors[error_entry->value] = error_entry; | | |
| 8998 | } | | |
| 8999 | ZigList<ErrorTableEntry *> intersection_list = {}; | 9034 | ZigList<ErrorTableEntry *> intersection_list = {}; |
| 9000 | | 9035 | |
| 9001 | ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); | 9036 | ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); |
| ... | @@ -10410,6 +10445,24 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod | ... | @@ -10410,6 +10445,24 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod |
| 10410 | return ir_exec_const_result(codegen, analyzed_executable); | 10445 | return ir_exec_const_result(codegen, analyzed_executable); |
| 10411 | } | 10446 | } |
| 10412 | | 10447 | |
| | 10448 | static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstruction *err_value) { |
| | 10449 | if (type_is_invalid(err_value->value.type)) |
| | 10450 | return nullptr; |
| | 10451 | |
| | 10452 | if (err_value->value.type->id != ZigTypeIdErrorSet) { |
| | 10453 | ir_add_error(ira, err_value, |
| | 10454 | buf_sprintf("expected error, found '%s'", buf_ptr(&err_value->value.type->name))); |
| | 10455 | return nullptr; |
| | 10456 | } |
| | 10457 | |
| | 10458 | ConstExprValue *const_val = ir_resolve_const(ira, err_value, UndefBad); |
| | 10459 | if (!const_val) |
| | 10460 | return nullptr; |
| | 10461 | |
| | 10462 | assert(const_val->data.x_err_set != nullptr); |
| | 10463 | return const_val->data.x_err_set; |
| | 10464 | } |
| | 10465 | |
| 10413 | static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { | 10466 | static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { |
| 10414 | if (type_is_invalid(type_value->value.type)) | 10467 | if (type_is_invalid(type_value->value.type)) |
| 10415 | return ira->codegen->builtin_types.entry_invalid; | 10468 | return ira->codegen->builtin_types.entry_invalid; |
| ... | @@ -17229,11 +17282,11 @@ static IrInstruction *ir_analyze_instruction_switch_br(IrAnalyze *ira, | ... | @@ -17229,11 +17282,11 @@ static IrInstruction *ir_analyze_instruction_switch_br(IrAnalyze *ira, |
| 17229 | } | 17282 | } |
| 17230 | | 17283 | |
| 17231 | IrBasicBlock *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block, &switch_br_instruction->base); | 17284 | IrBasicBlock *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block, &switch_br_instruction->base); |
| 17232 | IrInstruction *result = ir_build_switch_br(&ira->new_irb, | 17285 | IrInstructionSwitchBr *switch_br = ir_build_switch_br(&ira->new_irb, |
| 17233 | switch_br_instruction->base.scope, switch_br_instruction->base.source_node, | 17286 | switch_br_instruction->base.scope, switch_br_instruction->base.source_node, |
| 17234 | target_value, new_else_block, case_count, cases, nullptr, nullptr); | 17287 | target_value, new_else_block, case_count, cases, nullptr, nullptr); |
| 17235 | result->value.type = ira->codegen->builtin_types.entry_unreachable; | 17288 | switch_br->base.value.type = ira->codegen->builtin_types.entry_unreachable; |
| 17236 | return ir_finish_anal(ira, result); | 17289 | return ir_finish_anal(ira, &switch_br->base); |
| 17237 | } | 17290 | } |
| 17238 | | 17291 | |
| 17239 | static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, | 17292 | static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| ... | @@ -17419,6 +17472,85 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru | ... | @@ -17419,6 +17472,85 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru |
| 17419 | } | 17472 | } |
| 17420 | } | 17473 | } |
| 17421 | | 17474 | |
| | 17475 | static IrInstruction *ir_analyze_instruction_switch_else_var(IrAnalyze *ira, |
| | 17476 | IrInstructionSwitchElseVar *instruction) |
| | 17477 | { |
| | 17478 | IrInstruction *target_value_ptr = instruction->target_value_ptr->child; |
| | 17479 | if (type_is_invalid(target_value_ptr->value.type)) |
| | 17480 | return ira->codegen->invalid_instruction; |
| | 17481 | |
| | 17482 | ZigType *ref_type = target_value_ptr->value.type; |
| | 17483 | assert(ref_type->id == ZigTypeIdPointer); |
| | 17484 | ZigType *target_type = target_value_ptr->value.type->data.pointer.child_type; |
| | 17485 | if (target_type->id == ZigTypeIdErrorSet) { |
| | 17486 | // make a new set that has the other cases removed |
| | 17487 | if (!resolve_inferred_error_set(ira->codegen, target_type, instruction->base.source_node)) { |
| | 17488 | return ira->codegen->invalid_instruction; |
| | 17489 | } |
| | 17490 | if (type_is_global_error_set(target_type)) { |
| | 17491 | // the type of the else capture variable still has to be the global error set. |
| | 17492 | // once the runtime hint system is more sophisticated, we could add some hint information here. |
| | 17493 | return target_value_ptr; |
| | 17494 | } |
| | 17495 | // Make note of the errors handled by other cases |
| | 17496 | ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); |
| | 17497 | for (size_t case_i = 0; case_i < instruction->switch_br->case_count; case_i += 1) { |
| | 17498 | IrInstructionSwitchBrCase *br_case = &instruction->switch_br->cases[case_i]; |
| | 17499 | IrInstruction *case_expr = br_case->value->child; |
| | 17500 | if (case_expr->value.type->id == ZigTypeIdErrorSet) { |
| | 17501 | ErrorTableEntry *err = ir_resolve_error(ira, case_expr); |
| | 17502 | if (err == nullptr) |
| | 17503 | return ira->codegen->invalid_instruction; |
| | 17504 | errors[err->value] = err; |
| | 17505 | } else if (case_expr->value.type->id == ZigTypeIdMetaType) { |
| | 17506 | ZigType *err_set_type = ir_resolve_type(ira, case_expr); |
| | 17507 | if (type_is_invalid(err_set_type)) |
| | 17508 | return ira->codegen->invalid_instruction; |
| | 17509 | populate_error_set_table(errors, err_set_type); |
| | 17510 | } else { |
| | 17511 | zig_unreachable(); |
| | 17512 | } |
| | 17513 | } |
| | 17514 | ZigList<ErrorTableEntry *> result_list = {}; |
| | 17515 | |
| | 17516 | ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); |
| | 17517 | buf_resize(&err_set_type->name, 0); |
| | 17518 | buf_appendf(&err_set_type->name, "error{"); |
| | 17519 | |
| | 17520 | // Look at all the errors in the type switched on and add them to the result_list |
| | 17521 | // if they are not handled by cases. |
| | 17522 | for (uint32_t i = 0; i < target_type->data.error_set.err_count; i += 1) { |
| | 17523 | ErrorTableEntry *error_entry = target_type->data.error_set.errors[i]; |
| | 17524 | ErrorTableEntry *existing_entry = errors[error_entry->value]; |
| | 17525 | if (existing_entry == nullptr) { |
| | 17526 | result_list.append(error_entry); |
| | 17527 | buf_appendf(&err_set_type->name, "%s,", buf_ptr(&error_entry->name)); |
| | 17528 | } |
| | 17529 | } |
| | 17530 | free(errors); |
| | 17531 | |
| | 17532 | err_set_type->data.error_set.err_count = result_list.length; |
| | 17533 | err_set_type->data.error_set.errors = result_list.items; |
| | 17534 | err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; |
| | 17535 | err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; |
| | 17536 | err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; |
| | 17537 | |
| | 17538 | buf_appendf(&err_set_type->name, "}"); |
| | 17539 | |
| | 17540 | ZigType *new_target_value_ptr_type = get_pointer_to_type_extra(ira->codegen, |
| | 17541 | err_set_type, |
| | 17542 | ref_type->data.pointer.is_const, ref_type->data.pointer.is_volatile, |
| | 17543 | ref_type->data.pointer.ptr_len, |
| | 17544 | ref_type->data.pointer.explicit_alignment, |
| | 17545 | ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, |
| | 17546 | ref_type->data.pointer.allow_zero); |
| | 17547 | return ir_analyze_ptr_cast(ira, &instruction->base, target_value_ptr, new_target_value_ptr_type, |
| | 17548 | &instruction->base, false); |
| | 17549 | } |
| | 17550 | |
| | 17551 | return target_value_ptr; |
| | 17552 | } |
| | 17553 | |
| 17422 | static IrInstruction *ir_analyze_instruction_union_tag(IrAnalyze *ira, IrInstructionUnionTag *instruction) { | 17554 | static IrInstruction *ir_analyze_instruction_union_tag(IrAnalyze *ira, IrInstructionUnionTag *instruction) { |
| 17423 | IrInstruction *value = instruction->value->child; | 17555 | IrInstruction *value = instruction->value->child; |
| 17424 | return ir_analyze_union_tag(ira, &instruction->base, value); | 17556 | return ir_analyze_union_tag(ira, &instruction->base, value); |
| ... | @@ -23094,6 +23226,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23094,6 +23226,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23094 | return ir_analyze_instruction_switch_target(ira, (IrInstructionSwitchTarget *)instruction); | 23226 | return ir_analyze_instruction_switch_target(ira, (IrInstructionSwitchTarget *)instruction); |
| 23095 | case IrInstructionIdSwitchVar: | 23227 | case IrInstructionIdSwitchVar: |
| 23096 | return ir_analyze_instruction_switch_var(ira, (IrInstructionSwitchVar *)instruction); | 23228 | return ir_analyze_instruction_switch_var(ira, (IrInstructionSwitchVar *)instruction); |
| | 23229 | case IrInstructionIdSwitchElseVar: |
| | 23230 | return ir_analyze_instruction_switch_else_var(ira, (IrInstructionSwitchElseVar *)instruction); |
| 23097 | case IrInstructionIdUnionTag: | 23231 | case IrInstructionIdUnionTag: |
| 23098 | return ir_analyze_instruction_union_tag(ira, (IrInstructionUnionTag *)instruction); | 23232 | return ir_analyze_instruction_union_tag(ira, (IrInstructionUnionTag *)instruction); |
| 23099 | case IrInstructionIdImport: | 23233 | case IrInstructionIdImport: |
| ... | @@ -23457,6 +23591,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -23457,6 +23591,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23457 | case IrInstructionIdCtz: | 23591 | case IrInstructionIdCtz: |
| 23458 | case IrInstructionIdPopCount: | 23592 | case IrInstructionIdPopCount: |
| 23459 | case IrInstructionIdSwitchVar: | 23593 | case IrInstructionIdSwitchVar: |
| | 23594 | case IrInstructionIdSwitchElseVar: |
| 23460 | case IrInstructionIdSwitchTarget: | 23595 | case IrInstructionIdSwitchTarget: |
| 23461 | case IrInstructionIdUnionTag: | 23596 | case IrInstructionIdUnionTag: |
| 23462 | case IrInstructionIdRef: | 23597 | case IrInstructionIdRef: |