| ... | ... | @@ -991,9 +991,30 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 991 | 991 | TypeTableEntry *expr_type = get_expr_type(expr_node); |
| 992 | 992 | assert(expr_type->id == TypeTableEntryIdErrorUnion); |
| 993 | 993 | TypeTableEntry *child_type = expr_type->data.error.child_type; |
| 994 | | // TODO in debug mode, put a panic here if the error is not 0 |
| 994 | |
| 995 | if (g->build_type != CodeGenBuildTypeRelease) { |
| 996 | LLVMValueRef err_val; |
| 997 | if (child_type->size_in_bits > 0) { |
| 998 | add_debug_source_node(g, node); |
| 999 | LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 0, ""); |
| 1000 | err_val = LLVMBuildLoad(g->builder, err_val_ptr, ""); |
| 1001 | } else { |
| 1002 | err_val = expr_val; |
| 1003 | } |
| 1004 | LLVMValueRef zero = LLVMConstNull(g->err_tag_type->type_ref); |
| 1005 | LLVMValueRef cond_val = LLVMBuildICmp(g->builder, LLVMIntEQ, err_val, zero, ""); |
| 1006 | LLVMBasicBlockRef err_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapErrError"); |
| 1007 | LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapErrOk"); |
| 1008 | LLVMBuildCondBr(g->builder, cond_val, ok_block, err_block); |
| 1009 | |
| 1010 | LLVMPositionBuilderAtEnd(g->builder, err_block); |
| 1011 | LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, ""); |
| 1012 | LLVMBuildUnreachable(g->builder); |
| 1013 | |
| 1014 | LLVMPositionBuilderAtEnd(g->builder, ok_block); |
| 1015 | } |
| 1016 | |
| 995 | 1017 | if (child_type->size_in_bits > 0) { |
| 996 | | add_debug_source_node(g, node); |
| 997 | 1018 | LLVMValueRef child_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, ""); |
| 998 | 1019 | if (handle_is_ptr(child_type)) { |
| 999 | 1020 | return child_val_ptr; |
| ... | ... | @@ -1898,6 +1919,9 @@ static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) { |
| 1898 | 1919 | } else if (type_entry->id == TypeTableEntryIdUnreachable) { |
| 1899 | 1920 | assert(node->data.container_init_expr.entries.length == 0); |
| 1900 | 1921 | add_debug_source_node(g, node); |
| 1922 | if (g->build_type != CodeGenBuildTypeRelease) { |
| 1923 | LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, ""); |
| 1924 | } |
| 1901 | 1925 | return LLVMBuildUnreachable(g->builder); |
| 1902 | 1926 | } else if (type_entry->id == TypeTableEntryIdVoid) { |
| 1903 | 1927 | assert(node->data.container_init_expr.entries.length == 0); |
| ... | ... | @@ -3084,6 +3108,11 @@ static BuiltinFnEntry *create_builtin_fn_with_arg_count(CodeGen *g, BuiltinFnId |
| 3084 | 3108 | } |
| 3085 | 3109 | |
| 3086 | 3110 | static void define_builtin_fns(CodeGen *g) { |
| 3111 | { |
| 3112 | LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), nullptr, 0, false); |
| 3113 | g->trap_fn_val = LLVMAddFunction(g->module, "llvm.debugtrap", fn_type); |
| 3114 | assert(LLVMGetIntrinsicID(g->trap_fn_val)); |
| 3115 | } |
| 3087 | 3116 | { |
| 3088 | 3117 | BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdMemcpy, "memcpy"); |
| 3089 | 3118 | builtin_fn->return_type = g->builtin_types.entry_void; |