authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-05-14 20:40:14-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-05-18 15:32:34-07:00
logfbb6d1d7ee634ac04df7b53abec842c30fafefed
tree6570fd427b470b0f85231d566f16cf006841ec16
parent7edef4f3fd8e260c69142741e750b3e6893434b8

support extern C ABI for return types


2 files changed, 15 insertions(+), 6 deletions(-)

src/analyze.cpp+1-1
...@@ -702,7 +702,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {...@@ -702,7 +702,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
702702
703 // next, loop over the parameters again and compute debug information703 // next, loop over the parameters again and compute debug information
704 // and codegen information704 // and codegen information
705 bool first_arg_return = handle_is_ptr(fn_type_id->return_type);705 bool first_arg_return = !fn_type_id->is_extern && handle_is_ptr(fn_type_id->return_type);
706 // +1 for maybe making the first argument the return value706 // +1 for maybe making the first argument the return value
707 LLVMTypeRef *gen_param_types = allocate<LLVMTypeRef>(1 + fn_type_id->param_count);707 LLVMTypeRef *gen_param_types = allocate<LLVMTypeRef>(1 + fn_type_id->param_count);
708 // +1 because 0 is the return type and +1 for maybe making first arg ret val708 // +1 because 0 is the return type and +1 for maybe making first arg ret val
src/codegen.cpp+14-5
...@@ -2329,11 +2329,18 @@ static LLVMValueRef gen_return(CodeGen *g, AstNode *source_node, LLVMValueRef va...@@ -2329,11 +2329,18 @@ static LLVMValueRef gen_return(CodeGen *g, AstNode *source_node, LLVMValueRef va
2329 }2329 }
23302330
2331 TypeTableEntry *return_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type;2331 TypeTableEntry *return_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type;
2332 bool is_extern = g->cur_fn->type_entry->data.fn.fn_type_id.is_extern;
2332 if (handle_is_ptr(return_type)) {2333 if (handle_is_ptr(return_type)) {
2333 assert(g->cur_ret_ptr);2334 if (is_extern) {
2334 gen_assign_raw(g, source_node, BinOpTypeAssign, g->cur_ret_ptr, value, return_type, return_type);2335 set_debug_source_node(g, source_node);
2335 set_debug_source_node(g, source_node);2336 LLVMValueRef by_val_value = LLVMBuildLoad(g->builder, value, "");
2336 LLVMBuildRetVoid(g->builder);2337 LLVMBuildRet(g->builder, by_val_value);
2338 } else {
2339 assert(g->cur_ret_ptr);
2340 gen_assign_raw(g, source_node, BinOpTypeAssign, g->cur_ret_ptr, value, return_type, return_type);
2341 set_debug_source_node(g, source_node);
2342 LLVMBuildRetVoid(g->builder);
2343 }
2337 } else {2344 } else {
2338 set_debug_source_node(g, source_node);2345 set_debug_source_node(g, source_node);
2339 LLVMBuildRet(g->builder, value);2346 LLVMBuildRet(g->builder, value);
...@@ -3898,7 +3905,9 @@ static void do_code_gen(CodeGen *g) {...@@ -3898,7 +3905,9 @@ static void do_code_gen(CodeGen *g) {
3898 // nothing to do3905 // nothing to do
3899 } else if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdPointer) {3906 } else if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdPointer) {
3900 LLVMZigAddNonNullAttr(fn_table_entry->fn_value, 0);3907 LLVMZigAddNonNullAttr(fn_table_entry->fn_value, 0);
3901 } else if (handle_is_ptr(fn_type->data.fn.fn_type_id.return_type)) {3908 } else if (handle_is_ptr(fn_type->data.fn.fn_type_id.return_type) &&
3909 !fn_type->data.fn.fn_type_id.is_extern)
3910 {
3902 LLVMValueRef first_arg = LLVMGetParam(fn_table_entry->fn_value, 0);3911 LLVMValueRef first_arg = LLVMGetParam(fn_table_entry->fn_value, 0);
3903 LLVMAddAttribute(first_arg, LLVMStructRetAttribute);3912 LLVMAddAttribute(first_arg, LLVMStructRetAttribute);
3904 LLVMZigAddNonNullAttr(fn_table_entry->fn_value, 1);3913 LLVMZigAddNonNullAttr(fn_table_entry->fn_value, 1);