authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-24 20:13:08-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-24 20:13:08-07:00
log29a83f648b8f0b6f757e07e3b1a6e15e8764b670
tree0b69ffb1dcd590d32fcc0e14b09718bd723565ce
parentf5cc7f65a3764e90b0daaa0388f683589ee105e0

support the `%return` expression


1 files changed, 23 insertions(+), 6 deletions(-)

src/codegen.cpp+23-6
...@@ -1266,17 +1266,34 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) {...@@ -1266,17 +1266,34 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) {
1266 assert(value_type->id == TypeTableEntryIdErrorUnion);1266 assert(value_type->id == TypeTableEntryIdErrorUnion);
1267 TypeTableEntry *child_type = value_type->data.error.child_type;1267 TypeTableEntry *child_type = value_type->data.error.child_type;
12681268
1269 LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ErrReturnYes");1269 LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ErrRetReturn");
1270 LLVMBasicBlockRef continue_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ErrReturnNo");1270 LLVMBasicBlockRef continue_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ErrRetContinue");
12711271
1272 LLVMPositionBuilderAtEnd(g->builder, return_block);1272 add_debug_source_node(g, node);
1273 LLVMValueRef err_val;
1273 if (child_type->size_in_bits > 0) {1274 if (child_type->size_in_bits > 0) {
1274 zig_panic("TODO write the error tag value to sret");1275 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, value, 0, "");
1276 err_val = LLVMBuildLoad(g->builder, err_val_ptr, "");
1277 } else {
1278 err_val = value;
1279 }
1280 LLVMValueRef zero = LLVMConstNull(g->err_tag_type->type_ref);
1281 LLVMValueRef cond_val = LLVMBuildICmp(g->builder, LLVMIntEQ, err_val, zero, "");
1282 LLVMBuildCondBr(g->builder, cond_val, continue_block, return_block);
1283
1284 LLVMPositionBuilderAtEnd(g->builder, return_block);
1285 TypeTableEntry *return_type = g->cur_fn->type_entry->data.fn.src_return_type;
1286 if (return_type->id == TypeTableEntryIdPureError) {
1287 gen_return(g, node, err_val);
1288 } else if (return_type->id == TypeTableEntryIdErrorUnion) {
1289 assert(g->cur_ret_ptr);
1290
1275 add_debug_source_node(g, node);1291 add_debug_source_node(g, node);
1292 LLVMValueRef tag_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, 0, "");
1293 LLVMBuildStore(g->builder, err_val, tag_ptr);
1276 LLVMBuildRetVoid(g->builder);1294 LLVMBuildRetVoid(g->builder);
1277 } else {1295 } else {
1278 add_debug_source_node(g, node);1296 zig_unreachable();
1279 LLVMBuildRet(g->builder, value);
1280 }1297 }
12811298
1282 LLVMPositionBuilderAtEnd(g->builder, continue_block);1299 LLVMPositionBuilderAtEnd(g->builder, continue_block);