| ... | @@ -2704,6 +2704,32 @@ static bool skip_fn_codegen(CodeGen *g, FnTableEntry *fn_entry) { | ... | @@ -2704,6 +2704,32 @@ static bool skip_fn_codegen(CodeGen *g, FnTableEntry *fn_entry) { |
| 2704 | return fn_entry->ref_count == 0; | 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 | static void do_code_gen(CodeGen *g) { | 2733 | static void do_code_gen(CodeGen *g) { |
| 2708 | assert(!g->errors.length); | 2734 | assert(!g->errors.length); |
| 2709 | | 2735 | |
| ... | @@ -2817,7 +2843,7 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -2817,7 +2843,7 @@ static void do_code_gen(CodeGen *g) { |
| 2817 | } | 2843 | } |
| 2818 | | 2844 | |
| 2819 | if (fn_table_entry->is_test) { | 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 | next_test_index += 1; | 2847 | next_test_index += 1; |
| 2822 | } | 2848 | } |
| 2823 | } | 2849 | } |
| ... | @@ -2827,27 +2853,28 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -2827,27 +2853,28 @@ static void do_code_gen(CodeGen *g) { |
| 2827 | assert(g->test_fn_count > 0); | 2853 | assert(g->test_fn_count > 0); |
| 2828 | assert(next_test_index == g->test_fn_count); | 2854 | assert(next_test_index == g->test_fn_count); |
| 2829 | | 2855 | |
| 2830 | { | 2856 | LLVMValueRef test_fn_array_init = LLVMConstArray(LLVMTypeOf(test_fn_vals[0]), |
| 2831 | LLVMValueRef test_fn_array_val = LLVMConstArray(LLVMTypeOf(test_fn_vals[0]), | 2857 | test_fn_vals, g->test_fn_count); |
| 2832 | test_fn_vals, g->test_fn_count); | 2858 | LLVMValueRef test_fn_array_val = LLVMAddGlobal(g->module, |
| 2833 | LLVMValueRef global_value = LLVMAddGlobal(g->module, | 2859 | LLVMTypeOf(test_fn_array_init), ""); |
| 2834 | LLVMTypeOf(test_fn_array_val), "zig_test_fn_list"); | 2860 | LLVMSetInitializer(test_fn_array_val, test_fn_array_init); |
| 2835 | LLVMSetInitializer(global_value, test_fn_array_val); | 2861 | LLVMSetLinkage(test_fn_array_val, LLVMInternalLinkage); |
| 2836 | LLVMSetLinkage(global_value, LLVMExternalLinkage); | 2862 | LLVMSetGlobalConstant(test_fn_array_val, true); |
| 2837 | LLVMSetGlobalConstant(global_value, true); | 2863 | LLVMSetUnnamedAddr(test_fn_array_val, true); |
| 2838 | LLVMSetUnnamedAddr(global_value, true); | 2864 | |
| 2839 | } | 2865 | LLVMValueRef len_val = LLVMConstInt(g->builtin_types.entry_isize->type_ref, g->test_fn_count, false); |
| 2840 | | 2866 | LLVMTypeRef ptr_type = LLVMPointerType(LLVMTypeOf(test_fn_vals[0]), 0); |
| 2841 | { | 2867 | LLVMValueRef fields[] = { |
| 2842 | LLVMValueRef test_fn_count_val = LLVMConstInt(g->builtin_types.entry_isize->type_ref, | 2868 | LLVMConstBitCast(test_fn_array_val, ptr_type), |
| 2843 | g->test_fn_count, false); | 2869 | len_val, |
| 2844 | LLVMValueRef global_value = LLVMAddGlobal(g->module, | 2870 | }; |
| 2845 | LLVMTypeOf(test_fn_count_val), "zig_test_fn_count"); | 2871 | LLVMValueRef test_fn_slice_init = LLVMConstStruct(fields, 2, false); |
| 2846 | LLVMSetInitializer(global_value, test_fn_count_val); | 2872 | LLVMValueRef test_fn_slice_val = LLVMAddGlobal(g->module, |
| 2847 | LLVMSetLinkage(global_value, LLVMExternalLinkage); | 2873 | LLVMTypeOf(test_fn_slice_init), "zig_test_fn_list"); |
| 2848 | LLVMSetGlobalConstant(global_value, true); | 2874 | LLVMSetInitializer(test_fn_slice_val, test_fn_slice_init); |
| 2849 | LLVMSetUnnamedAddr(global_value, true); | 2875 | LLVMSetLinkage(test_fn_slice_val, LLVMExternalLinkage); |
| 2850 | } | 2876 | LLVMSetGlobalConstant(test_fn_slice_val, true); |
| | 2877 | LLVMSetUnnamedAddr(test_fn_slice_val, true); |
| 2851 | } | 2878 | } |
| 2852 | | 2879 | |
| 2853 | // Generate function definitions. | 2880 | // Generate function definitions. |