From 7c53230a61568411e1375e1230df1ceaf1e462de Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 26 Mar 2017 03:39:18 -0400 Subject: introduce copyable concept closes #103 --- src/codegen.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 66d3e35246..94aec5664d 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -261,6 +261,13 @@ static void addLLVMArgAttr(LLVMValueRef arg_val, unsigned param_index, const cha return addLLVMAttr(arg_val, param_index + 1, attr_name); } +static void addLLVMCallsiteAttr(LLVMValueRef call_instr, unsigned param_index, const char *attr_name) { + unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name)); + assert(kind_id != 0); + LLVMAttributeRef llvm_attr = LLVMCreateEnumAttribute(LLVMGetGlobalContext(), kind_id, 0); + LLVMAddCallSiteAttribute(call_instr, param_index + 1, llvm_attr); +} + static Buf *get_mangled_name(CodeGen *g, Buf *original_name, bool external_linkage) { if (external_linkage || g->external_symbol_names.maybe_get(original_name) == nullptr) { return original_name; @@ -1578,11 +1585,12 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr fn_type = instruction->fn_ref->value.type; } - TypeTableEntry *src_return_type = fn_type->data.fn.fn_type_id.return_type; + FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; + TypeTableEntry *src_return_type = fn_type_id->return_type; bool ret_has_bits = type_has_bits(src_return_type); bool first_arg_ret = ret_has_bits && handle_is_ptr(src_return_type); size_t actual_param_count = instruction->arg_count + (first_arg_ret ? 1 : 0); - bool is_var_args = fn_type->data.fn.fn_type_id.is_var_args; + bool is_var_args = fn_type_id->is_var_args; LLVMValueRef *gen_param_values = allocate(actual_param_count); size_t gen_param_index = 0; if (first_arg_ret) { @@ -1603,6 +1611,13 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr LLVMValueRef result = ZigLLVMBuildCall(g->builder, fn_val, gen_param_values, gen_param_index, fn_type->data.fn.calling_convention, ""); + for (size_t param_i = 0; param_i < fn_type_id->param_count; param_i += 1) { + FnGenParamInfo *gen_info = &fn_type->data.fn.gen_param_info[param_i]; + if (gen_info->is_byval) { + addLLVMCallsiteAttr(result, gen_info->gen_index, "byval"); + } + } + if (src_return_type->id == TypeTableEntryIdUnreachable) { return LLVMBuildUnreachable(g->builder); } else if (!ret_has_bits) { @@ -3376,7 +3391,7 @@ static void do_code_gen(CodeGen *g) { addLLVMArgAttr(fn_val, gen_index, "nonnull"); } if (is_byval) { - // TODO add byval attr? + addLLVMArgAttr(fn_val, gen_index, "byval"); } } -- cgit v1.2.3