diff options
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 61 |
1 files changed, 42 insertions, 19 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index 3e555a5778..3f4262364e 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1157,29 +1157,52 @@ static LLVMValueRef gen_while_expr(CodeGen *g, AstNode *node) { assert(node->data.while_expr.condition); assert(node->data.while_expr.body); - LLVMBasicBlockRef cond_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileCond"); - LLVMBasicBlockRef body_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileBody"); - LLVMBasicBlockRef end_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileEnd"); + if (get_expr_type(node)->id == TypeTableEntryIdUnreachable) { + // generate a forever loop. guarantees no break statements - add_debug_source_node(g, node); - LLVMBuildBr(g->builder, cond_block); - - LLVMPositionBuilderAtEnd(g->builder, cond_block); - LLVMValueRef cond_val = gen_expr(g, node->data.while_expr.condition); - add_debug_source_node(g, node->data.while_expr.condition); - LLVMBuildCondBr(g->builder, cond_val, body_block, end_block); - - LLVMPositionBuilderAtEnd(g->builder, body_block); - g->break_block_stack.append(end_block); - g->continue_block_stack.append(cond_block); - gen_expr(g, node->data.while_expr.body); - g->break_block_stack.pop(); - g->continue_block_stack.pop(); - if (get_expr_type(node->data.while_expr.body)->id != TypeTableEntryIdUnreachable) { + LLVMBasicBlockRef body_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileBody"); + + add_debug_source_node(g, node); + LLVMBuildBr(g->builder, body_block); + + LLVMPositionBuilderAtEnd(g->builder, body_block); + g->continue_block_stack.append(body_block); + gen_expr(g, node->data.while_expr.body); + g->continue_block_stack.pop(); + + if (get_expr_type(node->data.while_expr.body)->id != TypeTableEntryIdUnreachable) { + add_debug_source_node(g, node); + LLVMBuildBr(g->builder, body_block); + } + } else { + // generate a normal while loop + + LLVMBasicBlockRef cond_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileCond"); + LLVMBasicBlockRef body_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileBody"); + LLVMBasicBlockRef end_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileEnd"); + + add_debug_source_node(g, node); LLVMBuildBr(g->builder, cond_block); + + LLVMPositionBuilderAtEnd(g->builder, cond_block); + LLVMValueRef cond_val = gen_expr(g, node->data.while_expr.condition); + add_debug_source_node(g, node->data.while_expr.condition); + LLVMBuildCondBr(g->builder, cond_val, body_block, end_block); + + LLVMPositionBuilderAtEnd(g->builder, body_block); + g->break_block_stack.append(end_block); + g->continue_block_stack.append(cond_block); + gen_expr(g, node->data.while_expr.body); + g->break_block_stack.pop(); + g->continue_block_stack.pop(); + if (get_expr_type(node->data.while_expr.body)->id != TypeTableEntryIdUnreachable) { + add_debug_source_node(g, node); + LLVMBuildBr(g->builder, cond_block); + } + + LLVMPositionBuilderAtEnd(g->builder, end_block); } - LLVMPositionBuilderAtEnd(g->builder, end_block); return nullptr; } |
