| ... | ... | @@ -1755,12 +1755,16 @@ static LLVMValueRef ir_render_asm(CodeGen *g, IrExecutable *executable, IrInstru |
| 1755 | 1755 | static LLVMValueRef gen_non_null_bit(CodeGen *g, TypeTableEntry *maybe_type, LLVMValueRef maybe_handle) { |
| 1756 | 1756 | assert(maybe_type->id == TypeTableEntryIdMaybe); |
| 1757 | 1757 | TypeTableEntry *child_type = maybe_type->data.maybe.child_type; |
| 1758 | | bool maybe_is_ptr = (child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn); |
| 1759 | | if (maybe_is_ptr) { |
| 1760 | | return LLVMBuildICmp(g->builder, LLVMIntNE, maybe_handle, LLVMConstNull(maybe_type->type_ref), ""); |
| 1758 | if (child_type->zero_bits) { |
| 1759 | return maybe_handle; |
| 1761 | 1760 | } else { |
| 1762 | | LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, maybe_handle, maybe_null_index, ""); |
| 1763 | | return LLVMBuildLoad(g->builder, maybe_field_ptr, ""); |
| 1761 | bool maybe_is_ptr = (child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn); |
| 1762 | if (maybe_is_ptr) { |
| 1763 | return LLVMBuildICmp(g->builder, LLVMIntNE, maybe_handle, LLVMConstNull(maybe_type->type_ref), ""); |
| 1764 | } else { |
| 1765 | LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, maybe_handle, maybe_null_index, ""); |
| 1766 | return LLVMBuildLoad(g->builder, maybe_field_ptr, ""); |
| 1767 | } |
| 1764 | 1768 | } |
| 1765 | 1769 | } |
| 1766 | 1770 | |
| ... | ... | @@ -1779,7 +1783,6 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable, |
| 1779 | 1783 | TypeTableEntry *maybe_type = ptr_type->data.pointer.child_type; |
| 1780 | 1784 | assert(maybe_type->id == TypeTableEntryIdMaybe); |
| 1781 | 1785 | TypeTableEntry *child_type = maybe_type->data.maybe.child_type; |
| 1782 | | bool maybe_is_ptr = (child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn); |
| 1783 | 1786 | LLVMValueRef maybe_ptr = ir_llvm_value(g, instruction->value); |
| 1784 | 1787 | LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type, is_volatile); |
| 1785 | 1788 | if (ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on) { |
| ... | ... | @@ -1793,11 +1796,16 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable, |
| 1793 | 1796 | |
| 1794 | 1797 | LLVMPositionBuilderAtEnd(g->builder, ok_block); |
| 1795 | 1798 | } |
| 1796 | | if (maybe_is_ptr) { |
| 1797 | | return maybe_ptr; |
| 1799 | if (child_type->zero_bits) { |
| 1800 | return nullptr; |
| 1798 | 1801 | } else { |
| 1799 | | LLVMValueRef maybe_struct_ref = get_handle_value(g, maybe_ptr, maybe_type, is_volatile); |
| 1800 | | return LLVMBuildStructGEP(g->builder, maybe_struct_ref, maybe_child_index, ""); |
| 1802 | bool maybe_is_ptr = (child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn); |
| 1803 | if (maybe_is_ptr) { |
| 1804 | return maybe_ptr; |
| 1805 | } else { |
| 1806 | LLVMValueRef maybe_struct_ref = get_handle_value(g, maybe_ptr, maybe_type, is_volatile); |
| 1807 | return LLVMBuildStructGEP(g->builder, maybe_struct_ref, maybe_child_index, ""); |
| 1808 | } |
| 1801 | 1809 | } |
| 1802 | 1810 | } |
| 1803 | 1811 | |
| ... | ... | @@ -2319,6 +2327,10 @@ static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, I |
| 2319 | 2327 | |
| 2320 | 2328 | TypeTableEntry *child_type = wanted_type->data.maybe.child_type; |
| 2321 | 2329 | |
| 2330 | if (child_type->zero_bits) { |
| 2331 | return LLVMConstInt(LLVMInt1Type(), 1, false); |
| 2332 | } |
| 2333 | |
| 2322 | 2334 | LLVMValueRef payload_val = ir_llvm_value(g, instruction->value); |
| 2323 | 2335 | if (child_type->id == TypeTableEntryIdPointer || |
| 2324 | 2336 | child_type->id == TypeTableEntryIdFn) |
| ... | ... | @@ -2806,7 +2818,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 2806 | 2818 | case TypeTableEntryIdMaybe: |
| 2807 | 2819 | { |
| 2808 | 2820 | TypeTableEntry *child_type = canon_type->data.maybe.child_type; |
| 2809 | | if (child_type->id == TypeTableEntryIdPointer || |
| 2821 | if (child_type->zero_bits) { |
| 2822 | return LLVMConstInt(LLVMInt1Type(), const_val->data.x_maybe ? 1 : 0, false); |
| 2823 | } else if (child_type->id == TypeTableEntryIdPointer || |
| 2810 | 2824 | child_type->id == TypeTableEntryIdFn) |
| 2811 | 2825 | { |
| 2812 | 2826 | if (const_val->data.x_maybe) { |
| ... | ... | @@ -4322,7 +4336,10 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) { |
| 4322 | 4336 | case TypeTableEntryIdMaybe: |
| 4323 | 4337 | { |
| 4324 | 4338 | TypeTableEntry *child_type = type_entry->data.maybe.child_type; |
| 4325 | | if (child_type->id == TypeTableEntryIdPointer || |
| 4339 | if (child_type->zero_bits) { |
| 4340 | buf_init_from_str(out_buf, "bool"); |
| 4341 | return; |
| 4342 | } else if (child_type->id == TypeTableEntryIdPointer || |
| 4326 | 4343 | child_type->id == TypeTableEntryIdFn) |
| 4327 | 4344 | { |
| 4328 | 4345 | return get_c_type(g, child_type, out_buf); |