| ... | @@ -1028,8 +1028,49 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { | ... | @@ -1028,8 +1028,49 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 1028 | case PrefixOpUnwrapMaybe: | 1028 | case PrefixOpUnwrapMaybe: |
| 1029 | { | 1029 | { |
| 1030 | LLVMValueRef expr_val = gen_expr(g, expr_node); | 1030 | LLVMValueRef expr_val = gen_expr(g, expr_node); |
| 1031 | // TODO in debug mode, put a panic here if null | 1031 | |
| 1032 | return gen_unwrap_maybe(g, expr_node, expr_val); | 1032 | TypeTableEntry *expr_type = get_expr_type(expr_node); |
| | 1033 | assert(expr_type->id == TypeTableEntryIdMaybe); |
| | 1034 | TypeTableEntry *child_type = expr_type->data.maybe.child_type; |
| | 1035 | |
| | 1036 | if (g->build_type != CodeGenBuildTypeRelease) { |
| | 1037 | add_debug_source_node(g, node); |
| | 1038 | LLVMValueRef cond_val; |
| | 1039 | if (child_type->id == TypeTableEntryIdPointer || |
| | 1040 | child_type->id == TypeTableEntryIdFn) |
| | 1041 | { |
| | 1042 | cond_val = LLVMBuildICmp(g->builder, LLVMIntNE, expr_val, |
| | 1043 | LLVMConstNull(child_type->type_ref), ""); |
| | 1044 | } else { |
| | 1045 | LLVMValueRef maybe_null_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, ""); |
| | 1046 | cond_val = LLVMBuildLoad(g->builder, maybe_null_ptr, ""); |
| | 1047 | } |
| | 1048 | |
| | 1049 | LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapMaybeOk"); |
| | 1050 | LLVMBasicBlockRef null_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapMaybeNull"); |
| | 1051 | LLVMBuildCondBr(g->builder, cond_val, ok_block, null_block); |
| | 1052 | |
| | 1053 | LLVMPositionBuilderAtEnd(g->builder, null_block); |
| | 1054 | LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, ""); |
| | 1055 | LLVMBuildUnreachable(g->builder); |
| | 1056 | |
| | 1057 | LLVMPositionBuilderAtEnd(g->builder, ok_block); |
| | 1058 | } |
| | 1059 | |
| | 1060 | |
| | 1061 | if (child_type->id == TypeTableEntryIdPointer || |
| | 1062 | child_type->id == TypeTableEntryIdFn) |
| | 1063 | { |
| | 1064 | return expr_val; |
| | 1065 | } else { |
| | 1066 | add_debug_source_node(g, node); |
| | 1067 | LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, expr_val, 0, ""); |
| | 1068 | if (handle_is_ptr(child_type)) { |
| | 1069 | return maybe_field_ptr; |
| | 1070 | } else { |
| | 1071 | return LLVMBuildLoad(g->builder, maybe_field_ptr, ""); |
| | 1072 | } |
| | 1073 | } |
| 1033 | } | 1074 | } |
| 1034 | } | 1075 | } |
| 1035 | zig_unreachable(); | 1076 | zig_unreachable(); |