| ... | @@ -991,9 +991,30 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { | ... | @@ -991,9 +991,30 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 991 | TypeTableEntry *expr_type = get_expr_type(expr_node); | 991 | TypeTableEntry *expr_type = get_expr_type(expr_node); |
| 992 | assert(expr_type->id == TypeTableEntryIdErrorUnion); | 992 | assert(expr_type->id == TypeTableEntryIdErrorUnion); |
| 993 | TypeTableEntry *child_type = expr_type->data.error.child_type; | 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 | if (child_type->size_in_bits > 0) { | 1017 | if (child_type->size_in_bits > 0) { |
| 996 | add_debug_source_node(g, node); | | |
| 997 | LLVMValueRef child_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, ""); | 1018 | LLVMValueRef child_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, ""); |
| 998 | if (handle_is_ptr(child_type)) { | 1019 | if (handle_is_ptr(child_type)) { |
| 999 | return child_val_ptr; | 1020 | return child_val_ptr; |
| ... | @@ -1898,6 +1919,9 @@ static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) { | ... | @@ -1898,6 +1919,9 @@ static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) { |
| 1898 | } else if (type_entry->id == TypeTableEntryIdUnreachable) { | 1919 | } else if (type_entry->id == TypeTableEntryIdUnreachable) { |
| 1899 | assert(node->data.container_init_expr.entries.length == 0); | 1920 | assert(node->data.container_init_expr.entries.length == 0); |
| 1900 | add_debug_source_node(g, node); | 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 | return LLVMBuildUnreachable(g->builder); | 1925 | return LLVMBuildUnreachable(g->builder); |
| 1902 | } else if (type_entry->id == TypeTableEntryIdVoid) { | 1926 | } else if (type_entry->id == TypeTableEntryIdVoid) { |
| 1903 | assert(node->data.container_init_expr.entries.length == 0); | 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,6 +3108,11 @@ static BuiltinFnEntry *create_builtin_fn_with_arg_count(CodeGen *g, BuiltinFnId |
| 3084 | } | 3108 | } |
| 3085 | | 3109 | |
| 3086 | static void define_builtin_fns(CodeGen *g) { | 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 | BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdMemcpy, "memcpy"); | 3117 | BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdMemcpy, "memcpy"); |
| 3089 | builtin_fn->return_type = g->builtin_types.entry_void; | 3118 | builtin_fn->return_type = g->builtin_types.entry_void; |