authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-06 11:58:58-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-06 11:58:58-04:00
loga375bd0d9f5c7773598a8ea31af8c963d6a79706
treeb7f4b48651f44007ecf0b1cfaf2d61f4d3781df6
parent29923efb954aa6e3297e6c2010eaf92fdb977c53
signaturelock-open Commit is signed but in an unrecognized format.

stage1: compile error instead of incorrect code

for unimplemented C ABI See #1411 See #1481

1 files changed, 62 insertions(+), 28 deletions(-)

src/codegen.cpp+62-28
......@@ -3111,6 +3111,51 @@ static void set_call_instr_sret(CodeGen *g, LLVMValueRef call_instr) {
31113111 LLVMAddCallSiteAttribute(call_instr, 1, sret_attr);
31123112}
31133113
3114ATTRIBUTE_NORETURN
3115static void report_errors_and_exit(CodeGen *g) {
3116 assert(g->errors.length != 0);
3117 for (size_t i = 0; i < g->errors.length; i += 1) {
3118 ErrorMsg *err = g->errors.at(i);
3119 print_err_msg(err, g->err_color);
3120 }
3121 exit(1);
3122}
3123
3124static void report_errors_and_maybe_exit(CodeGen *g) {
3125 if (g->errors.length != 0) {
3126 report_errors_and_exit(g);
3127 }
3128}
3129
3130ATTRIBUTE_NORETURN
3131static void give_up_with_c_abi_error(CodeGen *g, AstNode *source_node) {
3132 ErrorMsg *msg = add_node_error(g, source_node,
3133 buf_sprintf("TODO: support C ABI for more targets. https://github.com/ziglang/zig/issues/1481"));
3134 add_error_note(g, msg, source_node,
3135 buf_sprintf("pointers, integers, floats, bools, and enums work on all targets"));
3136 report_errors_and_exit(g);
3137}
3138
3139static void gen_c_abi_param(CodeGen *g, ZigList<LLVMValueRef> *gen_param_values, LLVMValueRef val,
3140 ZigType *ty, AstNode *source_node)
3141{
3142 if (ty->id == ZigTypeIdInt ||
3143 ty->id == ZigTypeIdFloat ||
3144 ty->id == ZigTypeIdBool ||
3145 ty->id == ZigTypeIdEnum ||
3146 get_codegen_ptr_type(ty) != nullptr)
3147 {
3148 gen_param_values->append(val);
3149 return;
3150 }
3151
3152 if (g->zig_target.arch.arch == ZigLLVM_x86_64) {
3153 give_up_with_c_abi_error(g, source_node);
3154 } else {
3155 give_up_with_c_abi_error(g, source_node);
3156 }
3157}
3158
31143159static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCall *instruction) {
31153160 LLVMValueRef fn_val;
31163161 ZigType *fn_type;
......@@ -3128,29 +3173,25 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
31283173 ZigType *src_return_type = fn_type_id->return_type;
31293174 bool ret_has_bits = type_has_bits(src_return_type);
31303175
3176 CallingConvention cc = fn_type->data.fn.fn_type_id.cc;
3177 bool is_c_abi = cc == CallingConventionC;
3178
31313179 bool first_arg_ret = ret_has_bits && handle_is_ptr(src_return_type) &&
3132 calling_convention_does_first_arg_return(fn_type->data.fn.fn_type_id.cc);
3180 calling_convention_does_first_arg_return(cc);
31333181 bool prefix_arg_err_ret_stack = get_prefix_arg_err_ret_stack(g, fn_type_id);
3134 // +2 for the async args
3135 size_t actual_param_count = instruction->arg_count + (first_arg_ret ? 1 : 0) + (prefix_arg_err_ret_stack ? 1 : 0) + 2;
31363182 bool is_var_args = fn_type_id->is_var_args;
3137 LLVMValueRef *gen_param_values = allocate<LLVMValueRef>(actual_param_count);
3138 size_t gen_param_index = 0;
3183 ZigList<LLVMValueRef> gen_param_values = {};
31393184 if (first_arg_ret) {
3140 gen_param_values[gen_param_index] = instruction->tmp_ptr;
3141 gen_param_index += 1;
3185 gen_param_values.append(instruction->tmp_ptr);
31423186 }
31433187 if (prefix_arg_err_ret_stack) {
3144 gen_param_values[gen_param_index] = get_cur_err_ret_trace_val(g, instruction->base.scope);
3145 gen_param_index += 1;
3188 gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.scope));
31463189 }
31473190 if (instruction->is_async) {
3148 gen_param_values[gen_param_index] = ir_llvm_value(g, instruction->async_allocator);
3149 gen_param_index += 1;
3191 gen_param_values.append(ir_llvm_value(g, instruction->async_allocator));
31503192
31513193 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, "");
3152 gen_param_values[gen_param_index] = err_val_ptr;
3153 gen_param_index += 1;
3194 gen_param_values.append(err_val_ptr);
31543195 }
31553196 for (size_t call_i = 0; call_i < instruction->arg_count; call_i += 1) {
31563197 IrInstruction *param_instruction = instruction->args[call_i];
......@@ -3158,8 +3199,11 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
31583199 if (is_var_args || type_has_bits(param_type)) {
31593200 LLVMValueRef param_value = ir_llvm_value(g, param_instruction);
31603201 assert(param_value);
3161 gen_param_values[gen_param_index] = param_value;
3162 gen_param_index += 1;
3202 if (is_c_abi) {
3203 gen_c_abi_param(g, &gen_param_values, param_value, param_type, param_instruction->source_node);
3204 } else {
3205 gen_param_values.append(param_value);
3206 }
31633207 }
31643208 }
31653209
......@@ -3176,12 +3220,12 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
31763220 break;
31773221 }
31783222
3179 LLVMCallConv llvm_cc = get_llvm_cc(g, fn_type->data.fn.fn_type_id.cc);
3223 LLVMCallConv llvm_cc = get_llvm_cc(g, cc);
31803224 LLVMValueRef result;
31813225
31823226 if (instruction->new_stack == nullptr) {
31833227 result = ZigLLVMBuildCall(g->builder, fn_val,
3184 gen_param_values, (unsigned)gen_param_index, llvm_cc, fn_inline, "");
3228 gen_param_values.items, (unsigned)gen_param_values.length, llvm_cc, fn_inline, "");
31853229 } else {
31863230 LLVMValueRef stacksave_fn_val = get_stacksave_fn_val(g);
31873231 LLVMValueRef stackrestore_fn_val = get_stackrestore_fn_val(g);
......@@ -3190,7 +3234,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
31903234 LLVMValueRef old_stack_ref = LLVMBuildCall(g->builder, stacksave_fn_val, nullptr, 0, "");
31913235 gen_set_stack_pointer(g, new_stack_addr);
31923236 result = ZigLLVMBuildCall(g->builder, fn_val,
3193 gen_param_values, (unsigned)gen_param_index, llvm_cc, fn_inline, "");
3237 gen_param_values.items, (unsigned)gen_param_values.length, llvm_cc, fn_inline, "");
31943238 LLVMBuildCall(g->builder, stackrestore_fn_val, &old_stack_ref, 1, "");
31953239 }
31963240
......@@ -5735,16 +5779,6 @@ static void ensure_cache_dir(CodeGen *g) {
57355779 }
57365780}
57375781
5738static void report_errors_and_maybe_exit(CodeGen *g) {
5739 if (g->errors.length != 0) {
5740 for (size_t i = 0; i < g->errors.length; i += 1) {
5741 ErrorMsg *err = g->errors.at(i);
5742 print_err_msg(err, g->err_color);
5743 }
5744 exit(1);
5745 }
5746}
5747
57485782static void validate_inline_fns(CodeGen *g) {
57495783 for (size_t i = 0; i < g->inline_fns.length; i += 1) {
57505784 ZigFn *fn_entry = g->inline_fns.at(i);