From 029d37d6a7dc96f71dded5d5a9c8e7477aaa4146 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 10 Nov 2017 14:58:50 -0500 Subject: fix bug when multiple function definitions exist This might be related to #529 --- src/codegen.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 38a1a2cbea..248dc7a382 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -408,6 +408,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, buf_ptr(symbol_name)); if (existing_llvm_fn) { fn_table_entry->llvm_value = LLVMConstBitCast(existing_llvm_fn, LLVMPointerType(fn_llvm_type, 0)); + return fn_table_entry->llvm_value; } else { fn_table_entry->llvm_value = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_llvm_type); } -- cgit v1.2.3 From 019f18058bb74816f8754de63a219347597e06da Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 10 Nov 2017 16:32:37 -0500 Subject: fix test failures put all the codegen for fn prototypes to the same place --- example/cat/main.zig | 2 +- src/all_types.hpp | 6 +--- src/analyze.cpp | 3 -- src/codegen.cpp | 96 +++++++++++++++++++++++----------------------------- src/ir.cpp | 1 - 5 files changed, 45 insertions(+), 63 deletions(-) (limited to 'src/codegen.cpp') diff --git a/example/cat/main.zig b/example/cat/main.zig index 9027122913..00455968be 100644 --- a/example/cat/main.zig +++ b/example/cat/main.zig @@ -3,9 +3,9 @@ const io = std.io; const mem = std.mem; const os = std.os; const warn = std.debug.warn; +const allocator = std.debug.global_allocator; pub fn main() -> %void { - const allocator = &std.debug.global_allocator; var args_it = os.args(); const exe = %return unwrapArg(??args_it.next(allocator)); var catted_anything = false; diff --git a/src/all_types.hpp b/src/all_types.hpp index 797897e425..0b4efd8415 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1508,13 +1508,9 @@ struct CodeGen { bool linker_rdynamic; const char *linker_script; - // The function definitions this module includes. There must be a corresponding - // fn_protos entry. + // The function definitions this module includes. ZigList fn_defs; size_t fn_defs_index; - // The function prototypes this module includes. In the case of external declarations, - // there will not be a corresponding fn_defs entry. - ZigList fn_protos; ZigList global_vars; OutType out_type; diff --git a/src/analyze.cpp b/src/analyze.cpp index 7d46ebc908..343b1ecdb0 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -2121,8 +2121,6 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { } if (!fn_table_entry->type_entry->data.fn.is_generic) { - g->fn_protos.append(fn_table_entry); - if (fn_def_node) g->fn_defs.append(fn_table_entry); @@ -2162,7 +2160,6 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { fn_table_entry->body_node = source_node->data.test_decl.body; fn_table_entry->is_test = true; - g->fn_protos.append(fn_table_entry); g->fn_defs.append(fn_table_entry); g->test_fns.append(fn_table_entry); diff --git a/src/codegen.cpp b/src/codegen.cpp index 248dc7a382..17c0ffc653 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -494,6 +494,49 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { // use the ABI alignment, which is fine. } + if (!type_has_bits(fn_type->data.fn.fn_type_id.return_type)) { + // nothing to do + } else if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdPointer || + fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdFn) + { + addLLVMAttr(fn_table_entry->llvm_value, 0, "nonnull"); + } else if (handle_is_ptr(fn_type->data.fn.fn_type_id.return_type) && + calling_convention_does_first_arg_return(fn_type->data.fn.fn_type_id.cc)) + { + addLLVMArgAttr(fn_table_entry->llvm_value, 0, "sret"); + addLLVMArgAttr(fn_table_entry->llvm_value, 0, "nonnull"); + } + + + // set parameter attributes + for (size_t param_i = 0; param_i < fn_type->data.fn.fn_type_id.param_count; param_i += 1) { + FnGenParamInfo *gen_info = &fn_type->data.fn.gen_param_info[param_i]; + size_t gen_index = gen_info->gen_index; + bool is_byval = gen_info->is_byval; + + if (gen_index == SIZE_MAX) { + continue; + } + + FnTypeParamInfo *param_info = &fn_type->data.fn.fn_type_id.param_info[param_i]; + + TypeTableEntry *param_type = gen_info->type; + if (param_info->is_noalias) { + addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "noalias"); + } + if ((param_type->id == TypeTableEntryIdPointer && param_type->data.pointer.is_const) || is_byval) { + addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "readonly"); + } + if (param_type->id == TypeTableEntryIdPointer) { + addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "nonnull"); + } + // Note: byval is disabled on windows due to an LLVM bug: + // https://github.com/zig-lang/zig/issues/536 + if (is_byval && g->zig_target.os != ZigLLVM_Win32) { + addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "byval"); + } + } + return fn_table_entry->llvm_value; } @@ -4298,59 +4341,6 @@ static void do_code_gen(CodeGen *g) { var->value_ref = global_value; } - // Generate function prototypes - for (size_t fn_proto_i = 0; fn_proto_i < g->fn_protos.length; fn_proto_i += 1) { - FnTableEntry *fn_table_entry = g->fn_protos.at(fn_proto_i); - - TypeTableEntry *fn_type = fn_table_entry->type_entry; - FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; - - LLVMValueRef fn_val = fn_llvm_value(g, fn_table_entry); - - if (!type_has_bits(fn_type->data.fn.fn_type_id.return_type)) { - // nothing to do - } else if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdPointer || - fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdFn) - { - addLLVMAttr(fn_val, 0, "nonnull"); - } else if (handle_is_ptr(fn_type->data.fn.fn_type_id.return_type) && - calling_convention_does_first_arg_return(fn_type->data.fn.fn_type_id.cc)) - { - addLLVMArgAttr(fn_val, 0, "sret"); - addLLVMArgAttr(fn_val, 0, "nonnull"); - } - - - // set parameter attributes - 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]; - size_t gen_index = gen_info->gen_index; - bool is_byval = gen_info->is_byval; - - if (gen_index == SIZE_MAX) { - continue; - } - - FnTypeParamInfo *param_info = &fn_type_id->param_info[param_i]; - - TypeTableEntry *param_type = gen_info->type; - if (param_info->is_noalias) { - addLLVMArgAttr(fn_val, (unsigned)gen_index, "noalias"); - } - if ((param_type->id == TypeTableEntryIdPointer && param_type->data.pointer.is_const) || is_byval) { - addLLVMArgAttr(fn_val, (unsigned)gen_index, "readonly"); - } - if (param_type->id == TypeTableEntryIdPointer) { - addLLVMArgAttr(fn_val, (unsigned)gen_index, "nonnull"); - } - // Note: byval is disabled on windows due to an LLVM bug: - // https://github.com/zig-lang/zig/issues/536 - if (is_byval && g->zig_target.os != ZigLLVM_Win32) { - addLLVMArgAttr(fn_val, (unsigned)gen_index, "byval"); - } - } - } - // Generate function definitions. for (size_t fn_i = 0; fn_i < g->fn_defs.length; fn_i += 1) { FnTableEntry *fn_table_entry = g->fn_defs.at(fn_i); diff --git a/src/ir.cpp b/src/ir.cpp index 901ba47b76..fdaced6806 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -10584,7 +10584,6 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal impl_fn->analyzed_executable.source_node = call_instruction->base.source_node; impl_fn->analyzed_executable.parent_exec = ira->new_irb.exec; - ira->codegen->fn_protos.append(impl_fn); ira->codegen->fn_defs.append(impl_fn); } -- cgit v1.2.3