aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2015-12-03 00:47:35 -0700
committerAndrew Kelley <superjoe30@gmail.com>2015-12-03 00:47:35 -0700
commitf8ca6c70c74db6e6f0d4462aa763adb6f1f41c7e (patch)
tree99bc3d06bb37abb267a2a59f3ba04523c2c430eb /src/codegen.cpp
parentc89f77dd8e5005e60e8fb223c6c68b50566ac1ed (diff)
downloadzig-f8ca6c70c74db6e6f0d4462aa763adb6f1f41c7e.tar.gz
zig-f8ca6c70c74db6e6f0d4462aa763adb6f1f41c7e.zip
add labels and goto
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp39
1 files changed, 35 insertions, 4 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 13d72f6129..e91464771a 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -115,7 +115,7 @@ static LLVMValueRef get_variable_value(CodeGen *g, Buf *name) {
}
static TypeTableEntry *get_expr_type(AstNode *node) {
- return node->codegen_node->data.expr_node.type_entry;
+ return node->codegen_node->expr_node.type_entry;
}
static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {
@@ -407,11 +407,13 @@ static LLVMValueRef gen_if_expr(CodeGen *g, AstNode *node) {
LLVMPositionBuilderAtEnd(g->builder, then_block);
LLVMValueRef then_expr_result = gen_expr(g, node->data.if_expr.then_block);
- LLVMBuildBr(g->builder, endif_block);
+ if (get_expr_type(node->data.if_expr.then_block) != g->builtin_types.entry_unreachable)
+ LLVMBuildBr(g->builder, endif_block);
LLVMPositionBuilderAtEnd(g->builder, else_block);
LLVMValueRef else_expr_result = gen_expr(g, node->data.if_expr.else_node);
- LLVMBuildBr(g->builder, endif_block);
+ if (get_expr_type(node->data.if_expr.else_node) != g->builtin_types.entry_unreachable)
+ LLVMBuildBr(g->builder, endif_block);
LLVMPositionBuilderAtEnd(g->builder, endif_block);
if (use_expr_value) {
@@ -435,7 +437,8 @@ static LLVMValueRef gen_if_expr(CodeGen *g, AstNode *node) {
LLVMPositionBuilderAtEnd(g->builder, then_block);
gen_expr(g, node->data.if_expr.then_block);
- LLVMBuildBr(g->builder, endif_block);
+ if (get_expr_type(node->data.if_expr.then_block) != g->builtin_types.entry_unreachable)
+ LLVMBuildBr(g->builder, endif_block);
LLVMPositionBuilderAtEnd(g->builder, endif_block);
return nullptr;
@@ -518,6 +521,17 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
}
case NodeTypeBlock:
return gen_block(g, node, nullptr);
+ case NodeTypeGoto:
+ add_debug_source_node(g, node);
+ return LLVMBuildBr(g->builder, node->codegen_node->data.label_entry->basic_block);
+ case NodeTypeLabel:
+ {
+ LLVMBasicBlockRef basic_block = node->codegen_node->data.label_entry->basic_block;
+ add_debug_source_node(g, node);
+ LLVMValueRef result = LLVMBuildBr(g->builder, basic_block);
+ LLVMPositionBuilderAtEnd(g->builder, basic_block);
+ return result;
+ }
case NodeTypeRoot:
case NodeTypeRootExportDecl:
case NodeTypeFnProto:
@@ -533,6 +547,20 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
zig_unreachable();
}
+static void build_label_blocks(CodeGen *g, AstNode *block_node) {
+ assert(block_node->type == NodeTypeBlock);
+ for (int i = 0; i < block_node->data.block.statements.length; i += 1) {
+ AstNode *label_node = block_node->data.block.statements.at(i);
+ if (label_node->type != NodeTypeLabel)
+ continue;
+
+ Buf *name = &label_node->data.label.name;
+ label_node->codegen_node->data.label_entry->basic_block = LLVMAppendBasicBlock(
+ g->cur_fn->fn_value, buf_ptr(name));
+ }
+
+}
+
static LLVMZigDISubroutineType *create_di_function_type(CodeGen *g, AstNodeFnProto *fn_proto,
LLVMZigDIFile *di_file)
{
@@ -623,10 +651,13 @@ static void do_code_gen(CodeGen *g) {
codegen_fn_def->params = allocate<LLVMValueRef>(LLVMCountParams(fn));
LLVMGetParams(fn, codegen_fn_def->params);
+ build_label_blocks(g, fn_def_node->data.fn_def.body);
+
TypeTableEntry *implicit_return_type = codegen_fn_def->implicit_return_type;
gen_block(g, fn_def_node->data.fn_def.body, implicit_return_type);
g->block_scopes.pop();
+
}
assert(!g->errors.length);