| ... | @@ -353,10 +353,12 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { | ... | @@ -353,10 +353,12 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 353 | } else { | 353 | } else { |
| 354 | fn_table_entry->llvm_value = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_llvm_type); | 354 | fn_table_entry->llvm_value = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_llvm_type); |
| 355 | } | 355 | } |
| | 356 | fn_table_entry->llvm_name = LLVMGetValueName(fn_table_entry->llvm_value); |
| 356 | | 357 | |
| 357 | switch (fn_table_entry->fn_inline) { | 358 | switch (fn_table_entry->fn_inline) { |
| 358 | case FnInlineAlways: | 359 | case FnInlineAlways: |
| 359 | addLLVMFnAttr(fn_table_entry->llvm_value, "alwaysinline"); | 360 | addLLVMFnAttr(fn_table_entry->llvm_value, "alwaysinline"); |
| | 361 | g->inline_fns.append(fn_table_entry); |
| 360 | break; | 362 | break; |
| 361 | case FnInlineNever: | 363 | case FnInlineNever: |
| 362 | addLLVMFnAttr(fn_table_entry->llvm_value, "noinline"); | 364 | addLLVMFnAttr(fn_table_entry->llvm_value, "noinline"); |
| ... | @@ -3628,6 +3630,27 @@ static void ensure_cache_dir(CodeGen *g) { | ... | @@ -3628,6 +3630,27 @@ static void ensure_cache_dir(CodeGen *g) { |
| 3628 | } | 3630 | } |
| 3629 | } | 3631 | } |
| 3630 | | 3632 | |
| | 3633 | static void report_errors_and_maybe_exit(CodeGen *g) { |
| | 3634 | if (g->errors.length != 0) { |
| | 3635 | for (size_t i = 0; i < g->errors.length; i += 1) { |
| | 3636 | ErrorMsg *err = g->errors.at(i); |
| | 3637 | print_err_msg(err, g->err_color); |
| | 3638 | } |
| | 3639 | exit(1); |
| | 3640 | } |
| | 3641 | } |
| | 3642 | |
| | 3643 | static void validate_inline_fns(CodeGen *g) { |
| | 3644 | for (size_t i = 0; i < g->inline_fns.length; i += 1) { |
| | 3645 | FnTableEntry *fn_entry = g->inline_fns.at(i); |
| | 3646 | LLVMValueRef fn_val = LLVMGetNamedFunction(g->module, fn_entry->llvm_name); |
| | 3647 | if (fn_val != nullptr) { |
| | 3648 | add_node_error(g, fn_entry->proto_node, buf_sprintf("unable to inline function")); |
| | 3649 | } |
| | 3650 | } |
| | 3651 | report_errors_and_maybe_exit(g); |
| | 3652 | } |
| | 3653 | |
| 3631 | static void do_code_gen(CodeGen *g) { | 3654 | static void do_code_gen(CodeGen *g) { |
| 3632 | if (g->verbose) { | 3655 | if (g->verbose) { |
| 3633 | fprintf(stderr, "\nCode Generation:\n"); | 3656 | fprintf(stderr, "\nCode Generation:\n"); |
| ... | @@ -3927,6 +3950,8 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -3927,6 +3950,8 @@ static void do_code_gen(CodeGen *g) { |
| 3927 | zig_panic("unable to write object file: %s", err_msg); | 3950 | zig_panic("unable to write object file: %s", err_msg); |
| 3928 | } | 3951 | } |
| 3929 | | 3952 | |
| | 3953 | validate_inline_fns(g); |
| | 3954 | |
| 3930 | g->link_objects.append(output_path); | 3955 | g->link_objects.append(output_path); |
| 3931 | } | 3956 | } |
| 3932 | | 3957 | |
| ... | @@ -4719,16 +4744,9 @@ static void gen_root_source(CodeGen *g) { | ... | @@ -4719,16 +4744,9 @@ static void gen_root_source(CodeGen *g) { |
| 4719 | } | 4744 | } |
| 4720 | } | 4745 | } |
| 4721 | | 4746 | |
| 4722 | if (g->errors.length == 0) { | 4747 | report_errors_and_maybe_exit(g); |
| 4723 | if (g->verbose) { | 4748 | if (g->verbose) { |
| 4724 | fprintf(stderr, "OK\n"); | 4749 | fprintf(stderr, "OK\n"); |
| 4725 | } | | |
| 4726 | } else { | | |
| 4727 | for (size_t i = 0; i < g->errors.length; i += 1) { | | |
| 4728 | ErrorMsg *err = g->errors.at(i); | | |
| 4729 | print_err_msg(err, g->err_color); | | |
| 4730 | } | | |
| 4731 | exit(1); | | |
| 4732 | } | 4750 | } |
| 4733 | | 4751 | |
| 4734 | } | 4752 | } |