| ... | ... | @@ -3665,6 +3665,12 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con |
| 3665 | 3665 | zig_unreachable(); |
| 3666 | 3666 | } |
| 3667 | 3667 | |
| 3668 | // We have this because union constants can't be represented by the official union type, |
| 3669 | // and this property bubbles up in whatever aggregate type contains a union constant |
| 3670 | static bool is_llvm_value_unnamed_type(TypeTableEntry *type_entry, LLVMValueRef val) { |
| 3671 | return LLVMTypeOf(val) != type_entry->type_ref; |
| 3672 | } |
| 3673 | |
| 3668 | 3674 | static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3669 | 3675 | TypeTableEntry *type_entry = const_val->type; |
| 3670 | 3676 | assert(!type_entry->zero_bits); |
| ... | ... | @@ -3726,24 +3732,34 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3726 | 3732 | } else { |
| 3727 | 3733 | LLVMValueRef child_val; |
| 3728 | 3734 | LLVMValueRef maybe_val; |
| 3735 | bool make_unnamed_struct; |
| 3729 | 3736 | if (const_val->data.x_maybe) { |
| 3730 | 3737 | child_val = gen_const_val(g, const_val->data.x_maybe); |
| 3731 | 3738 | maybe_val = LLVMConstAllOnes(LLVMInt1Type()); |
| 3739 | |
| 3740 | make_unnamed_struct = is_llvm_value_unnamed_type(const_val->type, child_val); |
| 3732 | 3741 | } else { |
| 3733 | | child_val = LLVMConstNull(child_type->type_ref); |
| 3742 | child_val = LLVMGetUndef(child_type->type_ref); |
| 3734 | 3743 | maybe_val = LLVMConstNull(LLVMInt1Type()); |
| 3744 | |
| 3745 | make_unnamed_struct = false; |
| 3735 | 3746 | } |
| 3736 | 3747 | LLVMValueRef fields[] = { |
| 3737 | 3748 | child_val, |
| 3738 | 3749 | maybe_val, |
| 3739 | 3750 | }; |
| 3740 | | return LLVMConstStruct(fields, 2, false); |
| 3751 | if (make_unnamed_struct) { |
| 3752 | return LLVMConstStruct(fields, 2, false); |
| 3753 | } else { |
| 3754 | return LLVMConstNamedStruct(type_entry->type_ref, fields, 2); |
| 3755 | } |
| 3741 | 3756 | } |
| 3742 | 3757 | } |
| 3743 | 3758 | case TypeTableEntryIdStruct: |
| 3744 | 3759 | { |
| 3745 | 3760 | LLVMValueRef *fields = allocate<LLVMValueRef>(type_entry->data.structure.gen_field_count); |
| 3746 | 3761 | size_t src_field_count = type_entry->data.structure.src_field_count; |
| 3762 | bool make_unnamed_struct = false; |
| 3747 | 3763 | if (type_entry->data.structure.layout == ContainerLayoutPacked) { |
| 3748 | 3764 | size_t src_field_index = 0; |
| 3749 | 3765 | while (src_field_index < src_field_count) { |
| ... | ... | @@ -3761,8 +3777,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3761 | 3777 | } |
| 3762 | 3778 | |
| 3763 | 3779 | if (src_field_index + 1 == src_field_index_end) { |
| 3764 | | fields[type_struct_field->gen_index] = |
| 3765 | | gen_const_val(g, &const_val->data.x_struct.fields[src_field_index]); |
| 3780 | ConstExprValue *field_val = &const_val->data.x_struct.fields[src_field_index]; |
| 3781 | LLVMValueRef val = gen_const_val(g, field_val); |
| 3782 | fields[type_struct_field->gen_index] = val; |
| 3783 | make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(field_val->type, val); |
| 3766 | 3784 | } else { |
| 3767 | 3785 | LLVMTypeRef big_int_type_ref = LLVMStructGetTypeAtIndex(type_entry->type_ref, |
| 3768 | 3786 | (unsigned)type_struct_field->gen_index); |
| ... | ... | @@ -3790,11 +3808,18 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3790 | 3808 | if (type_struct_field->gen_index == SIZE_MAX) { |
| 3791 | 3809 | continue; |
| 3792 | 3810 | } |
| 3793 | | fields[type_struct_field->gen_index] = gen_const_val(g, &const_val->data.x_struct.fields[i]); |
| 3811 | ConstExprValue *field_val = &const_val->data.x_struct.fields[i]; |
| 3812 | LLVMValueRef val = gen_const_val(g, field_val); |
| 3813 | fields[type_struct_field->gen_index] = val; |
| 3814 | make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(field_val->type, val); |
| 3794 | 3815 | } |
| 3795 | 3816 | } |
| 3796 | | return LLVMConstStruct(fields, type_entry->data.structure.gen_field_count, |
| 3797 | | type_entry->data.structure.layout == ContainerLayoutPacked); |
| 3817 | if (make_unnamed_struct) { |
| 3818 | return LLVMConstStruct(fields, type_entry->data.structure.gen_field_count, |
| 3819 | type_entry->data.structure.layout == ContainerLayoutPacked); |
| 3820 | } else { |
| 3821 | return LLVMConstNamedStruct(type_entry->type_ref, fields, type_entry->data.structure.gen_field_count); |
| 3822 | } |
| 3798 | 3823 | } |
| 3799 | 3824 | case TypeTableEntryIdUnion: |
| 3800 | 3825 | { |
| ... | ... | @@ -3808,11 +3833,19 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3808 | 3833 | } |
| 3809 | 3834 | |
| 3810 | 3835 | LLVMValueRef *values = allocate<LLVMValueRef>(len); |
| 3836 | LLVMTypeRef element_type_ref = type_entry->data.array.child_type->type_ref; |
| 3837 | bool make_unnamed_struct = false; |
| 3811 | 3838 | for (uint64_t i = 0; i < len; i += 1) { |
| 3812 | 3839 | ConstExprValue *elem_value = &const_val->data.x_array.s_none.elements[i]; |
| 3813 | | values[i] = gen_const_val(g, elem_value); |
| 3840 | LLVMValueRef val = gen_const_val(g, elem_value); |
| 3841 | values[i] = val; |
| 3842 | make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(elem_value->type, val); |
| 3843 | } |
| 3844 | if (make_unnamed_struct) { |
| 3845 | return LLVMConstStruct(values, len, true); |
| 3846 | } else { |
| 3847 | return LLVMConstArray(element_type_ref, values, (unsigned)len); |
| 3814 | 3848 | } |
| 3815 | | return LLVMConstArray(LLVMTypeOf(values[0]), values, (unsigned)len); |
| 3816 | 3849 | } |
| 3817 | 3850 | case TypeTableEntryIdEnum: |
| 3818 | 3851 | { |
| ... | ... | @@ -3825,14 +3858,20 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3825 | 3858 | TypeEnumField *enum_field = &type_entry->data.enumeration.fields[const_val->data.x_enum.tag]; |
| 3826 | 3859 | assert(enum_field->value == const_val->data.x_enum.tag); |
| 3827 | 3860 | LLVMValueRef union_value; |
| 3861 | |
| 3862 | bool make_unnamed_struct; |
| 3863 | |
| 3828 | 3864 | if (type_has_bits(enum_field->type_entry)) { |
| 3829 | | uint64_t union_type_bytes = LLVMStoreSizeOfType(g->target_data_ref, |
| 3830 | | union_type_ref); |
| 3831 | 3865 | uint64_t field_type_bytes = LLVMStoreSizeOfType(g->target_data_ref, |
| 3832 | 3866 | enum_field->type_entry->type_ref); |
| 3833 | | uint64_t pad_bytes = union_type_bytes - field_type_bytes; |
| 3867 | uint64_t pad_bytes = type_entry->data.enumeration.union_size_bytes - field_type_bytes; |
| 3868 | |
| 3869 | ConstExprValue *payload_value = const_val->data.x_enum.payload; |
| 3870 | LLVMValueRef correctly_typed_value = gen_const_val(g, payload_value); |
| 3871 | |
| 3872 | make_unnamed_struct = is_llvm_value_unnamed_type(payload_value->type, correctly_typed_value) || |
| 3873 | payload_value->type != type_entry->data.enumeration.most_aligned_union_member; |
| 3834 | 3874 | |
| 3835 | | LLVMValueRef correctly_typed_value = gen_const_val(g, const_val->data.x_enum.payload); |
| 3836 | 3875 | if (pad_bytes == 0) { |
| 3837 | 3876 | union_value = correctly_typed_value; |
| 3838 | 3877 | } else { |
| ... | ... | @@ -3843,12 +3882,18 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3843 | 3882 | union_value = LLVMConstStruct(fields, 2, false); |
| 3844 | 3883 | } |
| 3845 | 3884 | } else { |
| 3885 | make_unnamed_struct = false; |
| 3846 | 3886 | union_value = LLVMGetUndef(union_type_ref); |
| 3847 | 3887 | } |
| 3848 | 3888 | LLVMValueRef fields[2]; |
| 3849 | 3889 | fields[type_entry->data.enumeration.gen_tag_index] = tag_value; |
| 3850 | 3890 | fields[type_entry->data.enumeration.gen_union_index] = union_value; |
| 3851 | | return LLVMConstStruct(fields, 2, false); |
| 3891 | |
| 3892 | if (make_unnamed_struct) { |
| 3893 | return LLVMConstStruct(fields, 2, false); |
| 3894 | } else { |
| 3895 | return LLVMConstNamedStruct(type_entry->type_ref, fields, 2); |
| 3896 | } |
| 3852 | 3897 | } |
| 3853 | 3898 | } |
| 3854 | 3899 | case TypeTableEntryIdFn: |
| ... | ... | @@ -3932,18 +3977,26 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3932 | 3977 | } else { |
| 3933 | 3978 | LLVMValueRef err_tag_value; |
| 3934 | 3979 | LLVMValueRef err_payload_value; |
| 3980 | bool make_unnamed_struct; |
| 3935 | 3981 | if (const_val->data.x_err_union.err) { |
| 3936 | 3982 | err_tag_value = LLVMConstInt(g->err_tag_type->type_ref, const_val->data.x_err_union.err->value, false); |
| 3937 | 3983 | err_payload_value = LLVMConstNull(child_type->type_ref); |
| 3984 | make_unnamed_struct = false; |
| 3938 | 3985 | } else { |
| 3939 | 3986 | err_tag_value = LLVMConstNull(g->err_tag_type->type_ref); |
| 3940 | | err_payload_value = gen_const_val(g, const_val->data.x_err_union.payload); |
| 3987 | ConstExprValue *payload_val = const_val->data.x_err_union.payload; |
| 3988 | err_payload_value = gen_const_val(g, payload_val); |
| 3989 | make_unnamed_struct = is_llvm_value_unnamed_type(payload_val->type, err_payload_value); |
| 3941 | 3990 | } |
| 3942 | 3991 | LLVMValueRef fields[] = { |
| 3943 | 3992 | err_tag_value, |
| 3944 | 3993 | err_payload_value, |
| 3945 | 3994 | }; |
| 3946 | | return LLVMConstStruct(fields, 2, false); |
| 3995 | if (make_unnamed_struct) { |
| 3996 | return LLVMConstStruct(fields, 2, false); |
| 3997 | } else { |
| 3998 | return LLVMConstNamedStruct(type_entry->type_ref, fields, 2); |
| 3999 | } |
| 3947 | 4000 | } |
| 3948 | 4001 | } |
| 3949 | 4002 | case TypeTableEntryIdVoid: |