aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-05-14 20:40:14 -0700
committerAndrew Kelley <superjoe30@gmail.com>2016-05-18 15:32:34 -0700
commitfbb6d1d7ee634ac04df7b53abec842c30fafefed (patch)
tree6570fd427b470b0f85231d566f16cf006841ec16 /src/codegen.cpp
parent7edef4f3fd8e260c69142741e750b3e6893434b8 (diff)
downloadzig-fbb6d1d7ee634ac04df7b53abec842c30fafefed.tar.gz
zig-fbb6d1d7ee634ac04df7b53abec842c30fafefed.zip
support extern C ABI for return types
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp19
1 files changed, 14 insertions, 5 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 122dac5b42..b25a3b6869 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -2329,11 +2329,18 @@ static LLVMValueRef gen_return(CodeGen *g, AstNode *source_node, LLVMValueRef va
}
TypeTableEntry *return_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type;
+ bool is_extern = g->cur_fn->type_entry->data.fn.fn_type_id.is_extern;
if (handle_is_ptr(return_type)) {
- assert(g->cur_ret_ptr);
- gen_assign_raw(g, source_node, BinOpTypeAssign, g->cur_ret_ptr, value, return_type, return_type);
- set_debug_source_node(g, source_node);
- LLVMBuildRetVoid(g->builder);
+ if (is_extern) {
+ set_debug_source_node(g, source_node);
+ LLVMValueRef by_val_value = LLVMBuildLoad(g->builder, value, "");
+ LLVMBuildRet(g->builder, by_val_value);
+ } else {
+ assert(g->cur_ret_ptr);
+ gen_assign_raw(g, source_node, BinOpTypeAssign, g->cur_ret_ptr, value, return_type, return_type);
+ set_debug_source_node(g, source_node);
+ LLVMBuildRetVoid(g->builder);
+ }
} else {
set_debug_source_node(g, source_node);
LLVMBuildRet(g->builder, value);
@@ -3898,7 +3905,9 @@ static void do_code_gen(CodeGen *g) {
// nothing to do
} else if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdPointer) {
LLVMZigAddNonNullAttr(fn_table_entry->fn_value, 0);
- } else if (handle_is_ptr(fn_type->data.fn.fn_type_id.return_type)) {
+ } else if (handle_is_ptr(fn_type->data.fn.fn_type_id.return_type) &&
+ !fn_type->data.fn.fn_type_id.is_extern)
+ {
LLVMValueRef first_arg = LLVMGetParam(fn_table_entry->fn_value, 0);
LLVMAddAttribute(first_arg, LLVMStructRetAttribute);
LLVMZigAddNonNullAttr(fn_table_entry->fn_value, 1);