| ... | @@ -1256,8 +1256,12 @@ static LLVMValueRef gen_cmp_expr(CodeGen *g, AstNode *node) { | ... | @@ -1256,8 +1256,12 @@ static LLVMValueRef gen_cmp_expr(CodeGen *g, AstNode *node) { |
| 1256 | op1_type->data.integral.is_signed); | 1256 | op1_type->data.integral.is_signed); |
| 1257 | return LLVMBuildICmp(g->builder, pred, val1, val2, ""); | 1257 | return LLVMBuildICmp(g->builder, pred, val1, val2, ""); |
| 1258 | } else if (op1_type->id == TypeTableEntryIdEnum) { | 1258 | } else if (op1_type->id == TypeTableEntryIdEnum) { |
| 1259 | LLVMIntPredicate pred = cmp_op_to_int_predicate(node->data.bin_op_expr.bin_op, false); | 1259 | if (op1_type->data.enumeration.gen_field_count == 0) { |
| 1260 | return LLVMBuildICmp(g->builder, pred, val1, val2, ""); | 1260 | LLVMIntPredicate pred = cmp_op_to_int_predicate(node->data.bin_op_expr.bin_op, false); |
| | 1261 | return LLVMBuildICmp(g->builder, pred, val1, val2, ""); |
| | 1262 | } else { |
| | 1263 | zig_unreachable(); |
| | 1264 | } |
| 1261 | } else { | 1265 | } else { |
| 1262 | zig_unreachable(); | 1266 | zig_unreachable(); |
| 1263 | } | 1267 | } |
| ... | @@ -2309,9 +2313,25 @@ static LLVMValueRef gen_symbol(CodeGen *g, AstNode *node) { | ... | @@ -2309,9 +2313,25 @@ static LLVMValueRef gen_symbol(CodeGen *g, AstNode *node) { |
| 2309 | static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) { | 2313 | static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) { |
| 2310 | assert(node->type == NodeTypeSwitchExpr); | 2314 | assert(node->type == NodeTypeSwitchExpr); |
| 2311 | | 2315 | |
| 2312 | LLVMValueRef target_value = gen_expr(g, node->data.switch_expr.expr); | 2316 | TypeTableEntry *target_type = get_expr_type(node->data.switch_expr.expr); |
| | 2317 | LLVMValueRef target_value_handle = gen_expr(g, node->data.switch_expr.expr); |
| | 2318 | LLVMValueRef target_value; |
| | 2319 | if (handle_is_ptr(target_type)) { |
| | 2320 | if (target_type->id == TypeTableEntryIdEnum) { |
| | 2321 | add_debug_source_node(g, node); |
| | 2322 | LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, target_value_handle, 0, ""); |
| | 2323 | target_value = LLVMBuildLoad(g->builder, tag_field_ptr, ""); |
| | 2324 | } else { |
| | 2325 | zig_unreachable(); |
| | 2326 | } |
| | 2327 | } else { |
| | 2328 | target_value = target_value_handle; |
| | 2329 | } |
| | 2330 | |
| 2313 | | 2331 | |
| 2314 | bool end_unreachable = (get_expr_type(node)->id == TypeTableEntryIdUnreachable); | 2332 | TypeTableEntry *switch_type = get_expr_type(node); |
| | 2333 | bool result_has_bits = type_has_bits(switch_type); |
| | 2334 | bool end_unreachable = (switch_type->id == TypeTableEntryIdUnreachable); |
| 2315 | | 2335 | |
| 2316 | LLVMBasicBlockRef end_block = end_unreachable ? | 2336 | LLVMBasicBlockRef end_block = end_unreachable ? |
| 2317 | nullptr : LLVMAppendBasicBlock(g->cur_fn->fn_value, "SwitchEnd"); | 2337 | nullptr : LLVMAppendBasicBlock(g->cur_fn->fn_value, "SwitchEnd"); |
| ... | @@ -2338,7 +2358,21 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) { | ... | @@ -2338,7 +2358,21 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) { |
| 2338 | AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); | 2358 | AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); |
| 2339 | assert(item_node->type != NodeTypeSwitchRange); | 2359 | assert(item_node->type != NodeTypeSwitchRange); |
| 2340 | assert(get_resolved_expr(item_node)->const_val.ok); | 2360 | assert(get_resolved_expr(item_node)->const_val.ok); |
| 2341 | LLVMValueRef val = gen_expr(g, item_node); | 2361 | LLVMValueRef val_handle = gen_expr(g, item_node); |
| | 2362 | LLVMValueRef val; |
| | 2363 | if (handle_is_ptr(target_type)) { |
| | 2364 | if (target_type->id == TypeTableEntryIdEnum) { |
| | 2365 | ConstExprValue *item_const_val = &get_resolved_expr(item_node)->const_val; |
| | 2366 | assert(item_const_val->ok); |
| | 2367 | assert(get_expr_type(item_node)->id == TypeTableEntryIdEnum); |
| | 2368 | val = LLVMConstInt(target_type->data.enumeration.tag_type->type_ref, |
| | 2369 | item_const_val->data.x_enum.tag, false); |
| | 2370 | } else { |
| | 2371 | zig_unreachable(); |
| | 2372 | } |
| | 2373 | } else { |
| | 2374 | val = val_handle; |
| | 2375 | } |
| 2342 | LLVMAddCase(switch_instr, val, prong_block); | 2376 | LLVMAddCase(switch_instr, val, prong_block); |
| 2343 | } | 2377 | } |
| 2344 | } | 2378 | } |
| ... | @@ -2367,11 +2401,14 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) { | ... | @@ -2367,11 +2401,14 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) { |
| 2367 | | 2401 | |
| 2368 | LLVMPositionBuilderAtEnd(g->builder, end_block); | 2402 | LLVMPositionBuilderAtEnd(g->builder, end_block); |
| 2369 | | 2403 | |
| 2370 | add_debug_source_node(g, node); | 2404 | if (result_has_bits) { |
| 2371 | LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMTypeOf(incoming_values.at(0)), ""); | 2405 | add_debug_source_node(g, node); |
| 2372 | LLVMAddIncoming(phi, incoming_values.items, incoming_blocks.items, incoming_values.length); | 2406 | LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMTypeOf(incoming_values.at(0)), ""); |
| 2373 | | 2407 | LLVMAddIncoming(phi, incoming_values.items, incoming_blocks.items, incoming_values.length); |
| 2374 | return phi; | 2408 | return phi; |
| | 2409 | } else { |
| | 2410 | return nullptr; |
| | 2411 | } |
| 2375 | } | 2412 | } |
| 2376 | | 2413 | |
| 2377 | static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { | 2414 | static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { |