| ... | ... | @@ -2704,6 +2704,32 @@ static bool skip_fn_codegen(CodeGen *g, FnTableEntry *fn_entry) { |
| 2704 | 2704 | return fn_entry->ref_count == 0; |
| 2705 | 2705 | } |
| 2706 | 2706 | |
| 2707 | static LLVMValueRef gen_test_fn_val(CodeGen *g, FnTableEntry *fn_entry) { |
| 2708 | // Must match TestFn struct from test_runner.zig |
| 2709 | Buf *fn_name = &fn_entry->symbol_name; |
| 2710 | LLVMValueRef str_init = LLVMConstString(buf_ptr(fn_name), buf_len(fn_name), true); |
| 2711 | LLVMValueRef str_global_val = LLVMAddGlobal(g->module, LLVMTypeOf(str_init), ""); |
| 2712 | LLVMSetInitializer(str_global_val, str_init); |
| 2713 | LLVMSetLinkage(str_global_val, LLVMPrivateLinkage); |
| 2714 | LLVMSetGlobalConstant(str_global_val, true); |
| 2715 | LLVMSetUnnamedAddr(str_global_val, true); |
| 2716 | |
| 2717 | LLVMValueRef len_val = LLVMConstInt(g->builtin_types.entry_isize->type_ref, buf_len(fn_name), false); |
| 2718 | |
| 2719 | LLVMTypeRef ptr_type = LLVMPointerType(g->builtin_types.entry_u8->type_ref, 0); |
| 2720 | LLVMValueRef name_fields[] = { |
| 2721 | LLVMConstBitCast(str_global_val, ptr_type), |
| 2722 | len_val, |
| 2723 | }; |
| 2724 | |
| 2725 | LLVMValueRef name_val = LLVMConstStruct(name_fields, 2, false); |
| 2726 | LLVMValueRef fields[] = { |
| 2727 | name_val, |
| 2728 | fn_entry->fn_value, |
| 2729 | }; |
| 2730 | return LLVMConstStruct(fields, 2, false); |
| 2731 | } |
| 2732 | |
| 2707 | 2733 | static void do_code_gen(CodeGen *g) { |
| 2708 | 2734 | assert(!g->errors.length); |
| 2709 | 2735 | |
| ... | ... | @@ -2817,7 +2843,7 @@ static void do_code_gen(CodeGen *g) { |
| 2817 | 2843 | } |
| 2818 | 2844 | |
| 2819 | 2845 | if (fn_table_entry->is_test) { |
| 2820 | | test_fn_vals[next_test_index] = fn_table_entry->fn_value; |
| 2846 | test_fn_vals[next_test_index] = gen_test_fn_val(g, fn_table_entry); |
| 2821 | 2847 | next_test_index += 1; |
| 2822 | 2848 | } |
| 2823 | 2849 | } |
| ... | ... | @@ -2827,27 +2853,28 @@ static void do_code_gen(CodeGen *g) { |
| 2827 | 2853 | assert(g->test_fn_count > 0); |
| 2828 | 2854 | assert(next_test_index == g->test_fn_count); |
| 2829 | 2855 | |
| 2830 | | { |
| 2831 | | LLVMValueRef test_fn_array_val = LLVMConstArray(LLVMTypeOf(test_fn_vals[0]), |
| 2832 | | test_fn_vals, g->test_fn_count); |
| 2833 | | LLVMValueRef global_value = LLVMAddGlobal(g->module, |
| 2834 | | LLVMTypeOf(test_fn_array_val), "zig_test_fn_list"); |
| 2835 | | LLVMSetInitializer(global_value, test_fn_array_val); |
| 2836 | | LLVMSetLinkage(global_value, LLVMExternalLinkage); |
| 2837 | | LLVMSetGlobalConstant(global_value, true); |
| 2838 | | LLVMSetUnnamedAddr(global_value, true); |
| 2839 | | } |
| 2840 | | |
| 2841 | | { |
| 2842 | | LLVMValueRef test_fn_count_val = LLVMConstInt(g->builtin_types.entry_isize->type_ref, |
| 2843 | | g->test_fn_count, false); |
| 2844 | | LLVMValueRef global_value = LLVMAddGlobal(g->module, |
| 2845 | | LLVMTypeOf(test_fn_count_val), "zig_test_fn_count"); |
| 2846 | | LLVMSetInitializer(global_value, test_fn_count_val); |
| 2847 | | LLVMSetLinkage(global_value, LLVMExternalLinkage); |
| 2848 | | LLVMSetGlobalConstant(global_value, true); |
| 2849 | | LLVMSetUnnamedAddr(global_value, true); |
| 2850 | | } |
| 2856 | LLVMValueRef test_fn_array_init = LLVMConstArray(LLVMTypeOf(test_fn_vals[0]), |
| 2857 | test_fn_vals, g->test_fn_count); |
| 2858 | LLVMValueRef test_fn_array_val = LLVMAddGlobal(g->module, |
| 2859 | LLVMTypeOf(test_fn_array_init), ""); |
| 2860 | LLVMSetInitializer(test_fn_array_val, test_fn_array_init); |
| 2861 | LLVMSetLinkage(test_fn_array_val, LLVMInternalLinkage); |
| 2862 | LLVMSetGlobalConstant(test_fn_array_val, true); |
| 2863 | LLVMSetUnnamedAddr(test_fn_array_val, true); |
| 2864 | |
| 2865 | LLVMValueRef len_val = LLVMConstInt(g->builtin_types.entry_isize->type_ref, g->test_fn_count, false); |
| 2866 | LLVMTypeRef ptr_type = LLVMPointerType(LLVMTypeOf(test_fn_vals[0]), 0); |
| 2867 | LLVMValueRef fields[] = { |
| 2868 | LLVMConstBitCast(test_fn_array_val, ptr_type), |
| 2869 | len_val, |
| 2870 | }; |
| 2871 | LLVMValueRef test_fn_slice_init = LLVMConstStruct(fields, 2, false); |
| 2872 | LLVMValueRef test_fn_slice_val = LLVMAddGlobal(g->module, |
| 2873 | LLVMTypeOf(test_fn_slice_init), "zig_test_fn_list"); |
| 2874 | LLVMSetInitializer(test_fn_slice_val, test_fn_slice_init); |
| 2875 | LLVMSetLinkage(test_fn_slice_val, LLVMExternalLinkage); |
| 2876 | LLVMSetGlobalConstant(test_fn_slice_val, true); |
| 2877 | LLVMSetUnnamedAddr(test_fn_slice_val, true); |
| 2851 | 2878 | } |
| 2852 | 2879 | |
| 2853 | 2880 | // Generate function definitions. |