void-payloads, multi-pattern arms, and range patterns (match statements)
This commit is contained in:
+14
-7
@@ -704,8 +704,11 @@ emit_instruction_stream :: proc(
|
||||
if item.kind == .Union {
|
||||
fields := types.fields_for(&emitter.module.types, instruction.type)
|
||||
field_index := int(instruction.integer)
|
||||
// A void-payload variant carries no value (`T{ variant }`): only the tag
|
||||
// is stored, so there is no operand to validate or write.
|
||||
void_payload := field_index >= 0 && field_index < len(fields) && types.is_void(fields[field_index].type)
|
||||
if field_index < 0 || field_index >= len(fields) ||
|
||||
!valid_value(instructions, instruction.args[0], fields[field_index].type, &emitter.module.types) {
|
||||
(!void_payload && !valid_value(instructions, instruction.args[0], fields[field_index].type, &emitter.module.types)) {
|
||||
emit_recovery_value(emitter, instruction_index, instruction, "invalid union aggregate operands")
|
||||
continue
|
||||
}
|
||||
@@ -725,13 +728,17 @@ emit_instruction_stream :: proc(
|
||||
}
|
||||
}
|
||||
fmt.sbprintf(&emitter.builder, " store %s %d, ptr %%union_slot%d\n", llvm_type(tag_enum, &emitter.module.types), tag_value, instruction_index)
|
||||
offset := types.union_payload_offset(instruction.type, &emitter.module.types, emitter.module.target)
|
||||
fmt.sbprintf(&emitter.builder, " %%union_payload%d = getelementptr i8, ptr %%union_slot%d, i64 %d\n", instruction_index, instruction_index, offset)
|
||||
payload_ptr = fmt.tprintf("%%union_payload%d", instruction_index)
|
||||
if !void_payload {
|
||||
offset := types.union_payload_offset(instruction.type, &emitter.module.types, emitter.module.target)
|
||||
fmt.sbprintf(&emitter.builder, " %%union_payload%d = getelementptr i8, ptr %%union_slot%d, i64 %d\n", instruction_index, instruction_index, offset)
|
||||
payload_ptr = fmt.tprintf("%%union_payload%d", instruction_index)
|
||||
}
|
||||
}
|
||||
if !void_payload {
|
||||
fmt.sbprintf(&emitter.builder, " store %s ", llvm_type(fields[field_index].type, &emitter.module.types))
|
||||
write_operand(&emitter.builder, instructions, instruction.args[0], fields[field_index].type, &emitter.module.types)
|
||||
fmt.sbprintf(&emitter.builder, ", ptr %s\n", payload_ptr)
|
||||
}
|
||||
fmt.sbprintf(&emitter.builder, " store %s ", llvm_type(fields[field_index].type, &emitter.module.types))
|
||||
write_operand(&emitter.builder, instructions, instruction.args[0], fields[field_index].type, &emitter.module.types)
|
||||
fmt.sbprintf(&emitter.builder, ", ptr %s\n", payload_ptr)
|
||||
fmt.sbprintf(&emitter.builder, " %%v%d = load %s, ptr %%union_slot%d\n", instruction_index, type_name, instruction_index)
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user