| ... | @@ -3329,9 +3329,21 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutableGen *executabl | ... | @@ -3329,9 +3329,21 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutableGen *executabl |
| 3329 | LLVMBasicBlockRef ok_value_block = LLVMAppendBasicBlock(g->cur_fn_val, "OkValue"); | 3329 | LLVMBasicBlockRef ok_value_block = LLVMAppendBasicBlock(g->cur_fn_val, "OkValue"); |
| 3330 | size_t field_count = wanted_type->data.enumeration.src_field_count; | 3330 | size_t field_count = wanted_type->data.enumeration.src_field_count; |
| 3331 | LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, tag_int_value, bad_value_block, field_count); | 3331 | LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, tag_int_value, bad_value_block, field_count); |
| | 3332 | |
| | 3333 | HashMap<BigInt, Buf *, bigint_hash, bigint_eql> occupied_tag_values = {}; |
| | 3334 | occupied_tag_values.init(field_count); |
| | 3335 | |
| 3332 | for (size_t field_i = 0; field_i < field_count; field_i += 1) { | 3336 | for (size_t field_i = 0; field_i < field_count; field_i += 1) { |
| | 3337 | TypeEnumField *type_enum_field = &wanted_type->data.enumeration.fields[field_i]; |
| | 3338 | |
| | 3339 | Buf *name = type_enum_field->name; |
| | 3340 | auto entry = occupied_tag_values.put_unique(type_enum_field->value, name); |
| | 3341 | if (entry != nullptr) { |
| | 3342 | continue; |
| | 3343 | } |
| | 3344 | |
| 3333 | LLVMValueRef this_tag_int_value = bigint_to_llvm_const(get_llvm_type(g, tag_int_type), | 3345 | LLVMValueRef this_tag_int_value = bigint_to_llvm_const(get_llvm_type(g, tag_int_type), |
| 3334 | &wanted_type->data.enumeration.fields[field_i].value); | 3346 | &type_enum_field->value); |
| 3335 | LLVMAddCase(switch_instr, this_tag_int_value, ok_value_block); | 3347 | LLVMAddCase(switch_instr, this_tag_int_value, ok_value_block); |
| 3336 | } | 3348 | } |
| 3337 | LLVMPositionBuilderAtEnd(g->builder, bad_value_block); | 3349 | LLVMPositionBuilderAtEnd(g->builder, bad_value_block); |