authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-06 12:03:07-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-06 12:03:07-04:00
log1a5bd8888174ef2eb1881c1dd81d418b44625cc7
treeda3b78b294e6d21271ae9095dffece83450cecdd
parent9cff23dbf9ff3da716a1c4397f9411eba09f6cac

alternate implementation of previous commit

This strategy adds another field to the SwitchBr instruction, which is the result of the CheckSwitchProngs instruction. The type of the result is void, and is unused, except that the SwitchBr instruction will not perform analysis if the CheckSwitchProngs instruction did not pass analysis. This allows the CheckSwitchProngs instruction to do implicit casting for its type checking, while preventing duplicate compile error messages.

2 files changed, 28 insertions(+), 17 deletions(-)

src/all_types.hpp+1
......@@ -2193,6 +2193,7 @@ struct IrInstructionSwitchBr {
21932193 size_t case_count;
21942194 IrInstructionSwitchBrCase *cases;
21952195 IrInstruction *is_comptime;
2196 IrInstruction *switch_prongs_void;
21962197};
21972198
21982199struct IrInstructionSwitchVar {
src/ir.cpp+27-17
......@@ -1719,7 +1719,8 @@ static IrInstruction *ir_build_ctz_from(IrBuilder *irb, IrInstruction *old_instr
17191719}
17201720
17211721static IrInstruction *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target_value,
1722 IrBasicBlock *else_block, size_t case_count, IrInstructionSwitchBrCase *cases, IrInstruction *is_comptime)
1722 IrBasicBlock *else_block, size_t case_count, IrInstructionSwitchBrCase *cases, IrInstruction *is_comptime,
1723 IrInstruction *switch_prongs_void)
17231724{
17241725 IrInstructionSwitchBr *instruction = ir_build_instruction<IrInstructionSwitchBr>(irb, scope, source_node);
17251726 instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable;
......@@ -1729,10 +1730,12 @@ static IrInstruction *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode *
17291730 instruction->case_count = case_count;
17301731 instruction->cases = cases;
17311732 instruction->is_comptime = is_comptime;
1733 instruction->switch_prongs_void = switch_prongs_void;
17321734
17331735 ir_ref_instruction(target_value, irb->current_basic_block);
17341736 if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block);
17351737 ir_ref_bb(else_block);
1738 if (switch_prongs_void) ir_ref_instruction(switch_prongs_void, irb->current_basic_block);
17361739
17371740 for (size_t i = 0; i < case_count; i += 1) {
17381741 ir_ref_instruction(cases[i].value, irb->current_basic_block);
......@@ -1744,10 +1747,10 @@ static IrInstruction *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode *
17441747
17451748static IrInstruction *ir_build_switch_br_from(IrBuilder *irb, IrInstruction *old_instruction,
17461749 IrInstruction *target_value, IrBasicBlock *else_block, size_t case_count,
1747 IrInstructionSwitchBrCase *cases, IrInstruction *is_comptime)
1750 IrInstructionSwitchBrCase *cases, IrInstruction *is_comptime, IrInstruction *switch_prongs_void)
17481751{
17491752 IrInstruction *new_instruction = ir_build_switch_br(irb, old_instruction->scope, old_instruction->source_node,
1750 target_value, else_block, case_count, cases, is_comptime);
1753 target_value, else_block, case_count, cases, is_comptime, switch_prongs_void);
17511754 ir_link_new_instruction(new_instruction, old_instruction);
17521755 return new_instruction;
17531756}
......@@ -6035,13 +6038,13 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
60356038
60366039 }
60376040
6038 ir_build_check_switch_prongs(irb, scope, node, target_value, check_ranges.items, check_ranges.length,
6041 IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, check_ranges.items, check_ranges.length,
60396042 else_prong != nullptr);
60406043
60416044 if (cases.length == 0) {
60426045 ir_build_br(irb, scope, node, else_block, is_comptime);
60436046 } else {
6044 ir_build_switch_br(irb, scope, node, target_value, else_block, cases.length, cases.items, is_comptime);
6047 ir_build_switch_br(irb, scope, node, target_value, else_block, cases.length, cases.items, is_comptime, switch_prongs_void);
60456048 }
60466049
60476050 if (!else_prong) {
......@@ -6692,7 +6695,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *parent_scope, Ast
66926695 cases[1].value = ir_build_const_u8(irb, parent_scope, node, 1);
66936696 cases[1].block = cleanup_block;
66946697 ir_build_switch_br(irb, parent_scope, node, suspend_code, irb->exec->coro_suspend_block,
6695 2, cases, const_bool_false);
6698 2, cases, const_bool_false, nullptr);
66966699
66976700 ir_set_cursor_at_end_and_append_block(irb, cleanup_block);
66986701 ir_gen_defers_for_block(irb, parent_scope, outer_scope, true);
......@@ -6773,7 +6776,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod
67736776 cases[1].value = ir_mark_gen(ir_build_const_u8(irb, parent_scope, node, 1));
67746777 cases[1].block = cleanup_block;
67756778 ir_mark_gen(ir_build_switch_br(irb, parent_scope, node, suspend_code, irb->exec->coro_suspend_block,
6776 2, cases, const_bool_false));
6779 2, cases, const_bool_false, nullptr));
67776780
67786781 ir_set_cursor_at_end_and_append_block(irb, cleanup_block);
67796782 ir_gen_defers_for_block(irb, parent_scope, outer_scope, true);
......@@ -7078,7 +7081,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
70787081 cases[0].block = invalid_resume_block;
70797082 cases[1].value = ir_build_const_u8(irb, scope, node, 1);
70807083 cases[1].block = irb->exec->coro_final_cleanup_block;
7081 ir_build_switch_br(irb, scope, node, suspend_code, irb->exec->coro_suspend_block, 2, cases, const_bool_false);
7084 ir_build_switch_br(irb, scope, node, suspend_code, irb->exec->coro_suspend_block, 2, cases, const_bool_false, nullptr);
70827085
70837086 ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_suspend_block);
70847087 ir_build_coro_end(irb, scope, node);
......@@ -15297,6 +15300,13 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira,
1529715300 if (type_is_invalid(target_value->value.type))
1529815301 return ir_unreach_error(ira);
1529915302
15303 if (switch_br_instruction->switch_prongs_void != nullptr) {
15304 if (type_is_invalid(switch_br_instruction->switch_prongs_void->other->value.type)) {
15305 return ir_unreach_error(ira);
15306 }
15307 }
15308
15309
1530015310 size_t case_count = switch_br_instruction->case_count;
1530115311
1530215312 bool is_comptime;
......@@ -15387,7 +15397,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira,
1538715397
1538815398 IrBasicBlock *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block, &switch_br_instruction->base);
1538915399 ir_build_switch_br_from(&ira->new_irb, &switch_br_instruction->base,
15390 target_value, new_else_block, case_count, cases, nullptr);
15400 target_value, new_else_block, case_count, cases, nullptr, nullptr);
1539115401 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
1539215402}
1539315403
......@@ -19136,27 +19146,27 @@ static TypeTableEntry *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira
1913619146 IrInstruction *start_value = range->start->other;
1913719147 if (type_is_invalid(start_value->value.type))
1913819148 return ira->codegen->builtin_types.entry_invalid;
19149 IrInstruction *casted_start_value = ir_implicit_cast(ira, start_value, switch_type);
19150 if (type_is_invalid(casted_start_value->value.type))
19151 return ira->codegen->builtin_types.entry_invalid;
1913919152
1914019153 IrInstruction *end_value = range->end->other;
1914119154 if (type_is_invalid(end_value->value.type))
1914219155 return ira->codegen->builtin_types.entry_invalid;
19156 IrInstruction *casted_end_value = ir_implicit_cast(ira, end_value, switch_type);
19157 if (type_is_invalid(casted_end_value->value.type))
19158 return ira->codegen->builtin_types.entry_invalid;
1914319159
19144 ConstExprValue *start_val = ir_resolve_const(ira, start_value, UndefBad);
19160 ConstExprValue *start_val = ir_resolve_const(ira, casted_start_value, UndefBad);
1914519161 if (!start_val)
1914619162 return ira->codegen->builtin_types.entry_invalid;
1914719163
19148 ConstExprValue *end_val = ir_resolve_const(ira, end_value, UndefBad);
19164 ConstExprValue *end_val = ir_resolve_const(ira, casted_end_value, UndefBad);
1914919165 if (!end_val)
1915019166 return ira->codegen->builtin_types.entry_invalid;
1915119167
19152 if (start_val->type->id == TypeTableEntryIdEnum)
19153 return ira->codegen->builtin_types.entry_invalid;
1915419168 assert(start_val->type->id == TypeTableEntryIdInt || start_val->type->id == TypeTableEntryIdComptimeInt);
19155
19156 if (end_val->type->id == TypeTableEntryIdEnum)
19157 return ira->codegen->builtin_types.entry_invalid;
1915819169 assert(end_val->type->id == TypeTableEntryIdInt || end_val->type->id == TypeTableEntryIdComptimeInt);
19159
1916019170 AstNode *prev_node = rangeset_add_range(&rs, &start_val->data.x_bigint, &end_val->data.x_bigint,
1916119171 start_value->source_node);
1916219172 if (prev_node != nullptr) {