diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2016-12-10 18:38:53 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2016-12-10 18:38:53 -0500 |
| commit | 6feae8a4e90118df26738316ab1fb49882ba6431 (patch) | |
| tree | 89c113d87eca49f10681c0b6c18c66f51ff0d6fb /src | |
| parent | 443e14afbd0615bd4902e53a31f70550a8d4497e (diff) | |
| download | zig-6feae8a4e90118df26738316ab1fb49882ba6431.tar.gz zig-6feae8a4e90118df26738316ab1fb49882ba6431.zip | |
IR: support error union type
Diffstat (limited to 'src')
| -rw-r--r-- | src/codegen.cpp | 14 | ||||
| -rw-r--r-- | src/ir.cpp | 40 |
2 files changed, 34 insertions, 20 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index 5ae2f96b8e..c828b42ed1 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -680,11 +680,6 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) { } assert(instruction->llvm_value); } - if (instruction->static_value.special != ConstValSpecialRuntime) { - if (instruction->type_entry->id == TypeTableEntryIdPointer) { - return LLVMBuildLoad(g->builder, instruction->static_value.llvm_global, ""); - } - } return instruction->llvm_value; } @@ -1794,7 +1789,14 @@ static LLVMValueRef ir_render_switch_br(CodeGen *g, IrExecutable *executable, Ir } static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutable *executable, IrInstructionPhi *instruction) { - LLVMValueRef phi = LLVMBuildPhi(g->builder, instruction->base.type_entry->type_ref, ""); + LLVMTypeRef phi_type; + if (handle_is_ptr(instruction->base.type_entry)) { + phi_type = LLVMPointerType(instruction->base.type_entry->type_ref, 0); + } else { + phi_type = instruction->base.type_entry->type_ref; + } + + LLVMValueRef phi = LLVMBuildPhi(g->builder, phi_type, ""); LLVMValueRef *incoming_values = allocate<LLVMValueRef>(instruction->incoming_count); LLVMBasicBlockRef *incoming_blocks = allocate<LLVMBasicBlockRef>(instruction->incoming_count); for (size_t i = 0; i < instruction->incoming_count; i += 1) { diff --git a/src/ir.cpp b/src/ir.cpp index d19f6d4430..d21cb852c5 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -3135,12 +3135,19 @@ static TypeTableEntry *ir_determine_peer_types(IrAnalyze *ira, AstNode *source_n if (prev_inst->type_entry->id == TypeTableEntryIdInvalid) { return ira->codegen->builtin_types.entry_invalid; } + bool any_are_pure_error = (prev_inst->type_entry->id == TypeTableEntryIdPureError); for (size_t i = 1; i < instruction_count; i += 1) { IrInstruction *cur_inst = instructions[i]; TypeTableEntry *cur_type = cur_inst->type_entry; TypeTableEntry *prev_type = prev_inst->type_entry; if (cur_type->id == TypeTableEntryIdInvalid) { return cur_type; + } else if (prev_type->id == TypeTableEntryIdPureError) { + prev_inst = cur_inst; + continue; + } else if (cur_type->id == TypeTableEntryIdPureError) { + any_are_pure_error = true; + continue; } else if (types_match_const_cast_only(prev_type, cur_type)) { continue; } else if (types_match_const_cast_only(cur_type, prev_type)) { @@ -3198,7 +3205,11 @@ static TypeTableEntry *ir_determine_peer_types(IrAnalyze *ira, AstNode *source_n return ira->codegen->builtin_types.entry_invalid; } } - return prev_inst->type_entry; + if (any_are_pure_error && prev_inst->type_entry->id != TypeTableEntryIdPureError) { + return get_error_type(ira->codegen, prev_inst->type_entry); + } else { + return prev_inst->type_entry; + } } enum ImplicitCastMatchResult { @@ -3304,6 +3315,14 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod return ir_determine_peer_types(ira, source_node, instructions, instruction_count); } +static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *type_entry) { + if (type_has_bits(type_entry) && handle_is_ptr(type_entry)) { + FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec); + assert(fn_entry); + fn_entry->alloca_list.append(instruction); + } +} + static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, TypeTableEntry *wanted_type, CastOp cast_op, bool need_alloca) { @@ -4696,11 +4715,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal impl_fn, nullptr, impl_param_count, casted_args); TypeTableEntry *return_type = impl_fn->type_entry->data.fn.fn_type_id.return_type; - if (type_has_bits(return_type) && handle_is_ptr(return_type)) { - FnTableEntry *callsite_fn = exec_fn_entry(ira->new_irb.exec); - assert(callsite_fn); - callsite_fn->alloca_list.append(new_call_instruction); - } + ir_add_alloca(ira, new_call_instruction, return_type); return ir_finish_anal(ira, return_type); } @@ -4752,12 +4767,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base, fn_entry, fn_ref, call_param_count, casted_args); - if (type_has_bits(return_type) && handle_is_ptr(return_type)) { - FnTableEntry *callsite_fn = exec_fn_entry(ira->new_irb.exec); - assert(callsite_fn); - callsite_fn->alloca_list.append(new_call_instruction); - } - + ir_add_alloca(ira, new_call_instruction, return_type); return ir_finish_anal(ira, return_type); } @@ -5280,6 +5290,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP ir_build_phi_from(&ira->new_irb, &phi_instruction->base, new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items); + return resolved_type; } @@ -6684,7 +6695,8 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru IrInstruction *new_instruction = ir_build_struct_init_from(&ira->new_irb, instruction, container_type, actual_field_count, new_fields); - fn_entry->alloca_list.append(new_instruction); + + ir_add_alloca(ira, new_instruction, container_type); return container_type; } @@ -6754,7 +6766,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira IrInstruction *new_instruction = ir_build_container_init_list_from(&ira->new_irb, &instruction->base, container_type_value, elem_count, new_items); - fn_entry->alloca_list.append(new_instruction); + ir_add_alloca(ira, new_instruction, fixed_size_array_type); return fixed_size_array_type; } else if (container_type->id == TypeTableEntryIdArray) { // same as slice init but we make a compile error if the length is wrong |
