aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp115
1 files changed, 45 insertions, 70 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp
index fb4c92dc4b..01ef7f2fef 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -1737,81 +1737,60 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) {
zig_unreachable();
}
-static LLVMValueRef gen_defer(CodeGen *g, AstNode *node) {
- assert(node->type == NodeTypeDefer);
-
-
- return nullptr;
-}
-
static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMValueRef cond_value,
AstNode *then_node, AstNode *else_node)
{
- TypeTableEntry *then_type = get_expr_type(then_node);
- bool use_expr_value = (then_type->id != TypeTableEntryIdUnreachable &&
- then_type->id != TypeTableEntryIdVoid);
-
- if (else_node) {
- LLVMBasicBlockRef then_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "Then");
- LLVMBasicBlockRef else_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "Else");
-
- LLVMBasicBlockRef endif_block;
- bool then_endif_reachable = get_expr_type(then_node)->id != TypeTableEntryIdUnreachable;
- bool else_endif_reachable = get_expr_type(else_node)->id != TypeTableEntryIdUnreachable;
- if (then_endif_reachable || else_endif_reachable) {
- endif_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "EndIf");
- }
+ assert(then_node);
+ assert(else_node);
- LLVMBuildCondBr(g->builder, cond_value, then_block, else_block);
-
- LLVMPositionBuilderAtEnd(g->builder, then_block);
- LLVMValueRef then_expr_result = gen_expr(g, then_node);
- if (then_endif_reachable) {
- LLVMBuildBr(g->builder, endif_block);
- }
- LLVMBasicBlockRef after_then_block = LLVMGetInsertBlock(g->builder);
-
- LLVMPositionBuilderAtEnd(g->builder, else_block);
- LLVMValueRef else_expr_result = gen_expr(g, else_node);
- if (else_endif_reachable) {
- LLVMBuildBr(g->builder, endif_block);
- }
- LLVMBasicBlockRef after_else_block = LLVMGetInsertBlock(g->builder);
+ TypeTableEntry *then_type = get_expr_type(then_node);
+ TypeTableEntry *else_type = get_expr_type(else_node);
- if (then_endif_reachable || else_endif_reachable) {
- LLVMPositionBuilderAtEnd(g->builder, endif_block);
- if (use_expr_value) {
- LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMTypeOf(then_expr_result), "");
- LLVMValueRef incoming_values[2] = {then_expr_result, else_expr_result};
- LLVMBasicBlockRef incoming_blocks[2] = {after_then_block, after_else_block};
- LLVMAddIncoming(phi, incoming_values, incoming_blocks, 2);
+ bool use_then_value = type_has_bits(then_type);
+ bool use_else_value = type_has_bits(else_type);
- return phi;
- }
- }
+ LLVMBasicBlockRef then_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "Then");
+ LLVMBasicBlockRef else_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "Else");
- return nullptr;
+ LLVMBasicBlockRef endif_block;
+ bool then_endif_reachable = then_type->id != TypeTableEntryIdUnreachable;
+ bool else_endif_reachable = else_type->id != TypeTableEntryIdUnreachable;
+ if (then_endif_reachable || else_endif_reachable) {
+ endif_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "EndIf");
}
- assert(!use_expr_value || then_type->id == TypeTableEntryIdErrorUnion);
-
- LLVMBasicBlockRef then_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "Then");
- LLVMBasicBlockRef endif_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "EndIf");
-
- LLVMBuildCondBr(g->builder, cond_value, then_block, endif_block);
+ LLVMBuildCondBr(g->builder, cond_value, then_block, else_block);
LLVMPositionBuilderAtEnd(g->builder, then_block);
- gen_expr(g, then_node);
- if (get_expr_type(then_node)->id != TypeTableEntryIdUnreachable)
+ LLVMValueRef then_expr_result = gen_expr(g, then_node);
+ if (then_endif_reachable) {
LLVMBuildBr(g->builder, endif_block);
+ }
+ LLVMBasicBlockRef after_then_block = LLVMGetInsertBlock(g->builder);
- LLVMPositionBuilderAtEnd(g->builder, endif_block);
-
- if (use_expr_value) {
- return LLVMConstNull(g->err_tag_type->type_ref);
- } else {
- return nullptr;
+ LLVMPositionBuilderAtEnd(g->builder, else_block);
+ LLVMValueRef else_expr_result = gen_expr(g, else_node);
+ if (else_endif_reachable) {
+ LLVMBuildBr(g->builder, endif_block);
}
+ LLVMBasicBlockRef after_else_block = LLVMGetInsertBlock(g->builder);
+
+ if (then_endif_reachable || else_endif_reachable) {
+ LLVMPositionBuilderAtEnd(g->builder, endif_block);
+ if (use_then_value && use_else_value) {
+ LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMTypeOf(then_expr_result), "");
+ LLVMValueRef incoming_values[2] = {then_expr_result, else_expr_result};
+ LLVMBasicBlockRef incoming_blocks[2] = {after_then_block, after_else_block};
+ LLVMAddIncoming(phi, incoming_values, incoming_blocks, 2);
+ return phi;
+ } else if (use_then_value) {
+ return then_expr_result;
+ } else if (use_else_value) {
+ return else_expr_result;
+ }
+ }
+
+ return nullptr;
}
static LLVMValueRef gen_if_bool_expr(CodeGen *g, AstNode *node) {
@@ -1866,14 +1845,6 @@ static LLVMValueRef gen_if_var_expr(CodeGen *g, AstNode *node) {
return return_value;
}
-//static int block_exit_path_count(BlockContext *block_context) {
-// int sum = 0;
-// for (int i = 0; i < BlockExitPathCount; i += 1) {
-// sum += block_context->block_exit_paths[i] ? 1 : 0;
-// }
-// return sum;
-//}
-
static LLVMValueRef gen_block(CodeGen *g, AstNode *block_node, TypeTableEntry *implicit_return_type) {
assert(block_node->type == NodeTypeBlock);
@@ -2553,7 +2524,8 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
case NodeTypeReturnExpr:
return gen_return_expr(g, node);
case NodeTypeDefer:
- return gen_defer(g, node);
+ // nothing to do
+ return nullptr;
case NodeTypeVariableDeclaration:
return gen_var_decl_expr(g, node);
case NodeTypePrefixOpExpr:
@@ -3191,6 +3163,7 @@ static const CIntTypeInfo c_int_type_infos[] = {
static int get_c_type_size_in_bits(CodeGen *g, CIntType id) {
// TODO other architectures besides x86_64
+ // other operating systems besides linux
switch (id) {
case CIntTypeShort:
case CIntTypeUShort:
@@ -3203,6 +3176,8 @@ static int get_c_type_size_in_bits(CodeGen *g, CIntType id) {
case CIntTypeLongLong:
case CIntTypeULongLong:
return 64;
+ case CIntTypeCount:
+ zig_unreachable();
}
zig_unreachable();
}