| author | |
| committer | |
| log | 2dfb1ebee2bc215271e5416b723d746af319621b |
| tree | 9b859eebd0926cb82c7370362baafec617e763dc |
| parent | d6b01931ef8a04777ae198af323c2b6ba998f7b1 |
Before, if you did something like:
```
const hi1 = "hi";
const hi2 = hi1;
```
This would create the "hi" data twice in the built object.
But since the value is const we don't have to duplicate the
data, now we take advantage of this fact.
closes #3368 files changed, 160 insertions(+), 84 deletions(-)
src/all_types.hpp+7-2| ... | @@ -210,11 +210,15 @@ struct ConstFn { | ... | @@ -210,11 +210,15 @@ struct ConstFn { |
| 210 | FnTableEntry *fn_entry; | 210 | FnTableEntry *fn_entry; |
| 211 | }; | 211 | }; |
| 212 | 212 | ||
| 213 | struct ConstGlobalRefs { | ||
| 214 | LLVMValueRef llvm_value; | ||
| 215 | LLVMValueRef llvm_global; | ||
| 216 | }; | ||
| 217 | |||
| 213 | struct ConstExprValue { | 218 | struct ConstExprValue { |
| 214 | TypeTableEntry *type; | 219 | TypeTableEntry *type; |
| 215 | ConstValSpecial special; | 220 | ConstValSpecial special; |
| 216 | LLVMValueRef llvm_value; | 221 | ConstGlobalRefs *global_refs; |
| 217 | LLVMValueRef llvm_global; | ||
| 218 | 222 | ||
| 219 | union { | 223 | union { |
| 220 | // populated if special == ConstValSpecialStatic | 224 | // populated if special == ConstValSpecialStatic |
| ... | @@ -527,6 +531,7 @@ enum CastOp { | ... | @@ -527,6 +531,7 @@ enum CastOp { |
| 527 | CastOpBoolToInt, | 531 | CastOpBoolToInt, |
| 528 | CastOpResizeSlice, | 532 | CastOpResizeSlice, |
| 529 | CastOpBytesToSlice, | 533 | CastOpBytesToSlice, |
| 534 | CastOpNumLitToConcrete, | ||
| 530 | }; | 535 | }; |
| 531 | 536 | ||
| 532 | struct AstNodeFnCallExpr { | 537 | struct AstNodeFnCallExpr { |
src/analyze.cpp+39-22| ... | @@ -3457,7 +3457,7 @@ bool type_requires_comptime(TypeTableEntry *type_entry) { | ... | @@ -3457,7 +3457,7 @@ bool type_requires_comptime(TypeTableEntry *type_entry) { |
| 3457 | void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { | 3457 | void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { |
| 3458 | const_val->special = ConstValSpecialStatic; | 3458 | const_val->special = ConstValSpecialStatic; |
| 3459 | const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str)); | 3459 | const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str)); |
| 3460 | const_val->data.x_array.s_none.elements = allocate<ConstExprValue>(buf_len(str)); | 3460 | const_val->data.x_array.s_none.elements = create_const_vals(buf_len(str)); |
| 3461 | 3461 | ||
| 3462 | for (size_t i = 0; i < buf_len(str); i += 1) { | 3462 | for (size_t i = 0; i < buf_len(str); i += 1) { |
| 3463 | ConstExprValue *this_char = &const_val->data.x_array.s_none.elements[i]; | 3463 | ConstExprValue *this_char = &const_val->data.x_array.s_none.elements[i]; |
| ... | @@ -3468,7 +3468,7 @@ void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { | ... | @@ -3468,7 +3468,7 @@ void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { |
| 3468 | } | 3468 | } |
| 3469 | 3469 | ||
| 3470 | ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) { | 3470 | ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) { |
| 3471 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | 3471 | ConstExprValue *const_val = create_const_vals(1); |
| 3472 | init_const_str_lit(g, const_val, str); | 3472 | init_const_str_lit(g, const_val, str); |
| 3473 | return const_val; | 3473 | return const_val; |
| 3474 | } | 3474 | } |
| ... | @@ -3476,10 +3476,10 @@ ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) { | ... | @@ -3476,10 +3476,10 @@ ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) { |
| 3476 | void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { | 3476 | void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { |
| 3477 | // first we build the underlying array | 3477 | // first we build the underlying array |
| 3478 | size_t len_with_null = buf_len(str) + 1; | 3478 | size_t len_with_null = buf_len(str) + 1; |
| 3479 | ConstExprValue *array_val = allocate<ConstExprValue>(1); | 3479 | ConstExprValue *array_val = create_const_vals(1); |
| 3480 | array_val->special = ConstValSpecialStatic; | 3480 | array_val->special = ConstValSpecialStatic; |
| 3481 | array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null); | 3481 | array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null); |
| 3482 | array_val->data.x_array.s_none.elements = allocate<ConstExprValue>(len_with_null); | 3482 | array_val->data.x_array.s_none.elements = create_const_vals(len_with_null); |
| 3483 | for (size_t i = 0; i < buf_len(str); i += 1) { | 3483 | for (size_t i = 0; i < buf_len(str); i += 1) { |
| 3484 | ConstExprValue *this_char = &array_val->data.x_array.s_none.elements[i]; | 3484 | ConstExprValue *this_char = &array_val->data.x_array.s_none.elements[i]; |
| 3485 | this_char->special = ConstValSpecialStatic; | 3485 | this_char->special = ConstValSpecialStatic; |
| ... | @@ -3500,7 +3500,7 @@ void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { | ... | @@ -3500,7 +3500,7 @@ void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { |
| 3500 | const_val->data.x_ptr.data.base_array.is_cstr = true; | 3500 | const_val->data.x_ptr.data.base_array.is_cstr = true; |
| 3501 | } | 3501 | } |
| 3502 | ConstExprValue *create_const_c_str_lit(CodeGen *g, Buf *str) { | 3502 | ConstExprValue *create_const_c_str_lit(CodeGen *g, Buf *str) { |
| 3503 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | 3503 | ConstExprValue *const_val = create_const_vals(1); |
| 3504 | init_const_c_str_lit(g, const_val, str); | 3504 | init_const_c_str_lit(g, const_val, str); |
| 3505 | return const_val; | 3505 | return const_val; |
| 3506 | } | 3506 | } |
| ... | @@ -3513,7 +3513,7 @@ void init_const_unsigned_negative(ConstExprValue *const_val, TypeTableEntry *typ | ... | @@ -3513,7 +3513,7 @@ void init_const_unsigned_negative(ConstExprValue *const_val, TypeTableEntry *typ |
| 3513 | } | 3513 | } |
| 3514 | 3514 | ||
| 3515 | ConstExprValue *create_const_unsigned_negative(TypeTableEntry *type, uint64_t x, bool negative) { | 3515 | ConstExprValue *create_const_unsigned_negative(TypeTableEntry *type, uint64_t x, bool negative) { |
| 3516 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | 3516 | ConstExprValue *const_val = create_const_vals(1); |
| 3517 | init_const_unsigned_negative(const_val, type, x, negative); | 3517 | init_const_unsigned_negative(const_val, type, x, negative); |
| 3518 | return const_val; | 3518 | return const_val; |
| 3519 | } | 3519 | } |
| ... | @@ -3533,7 +3533,7 @@ void init_const_signed(ConstExprValue *const_val, TypeTableEntry *type, int64_t | ... | @@ -3533,7 +3533,7 @@ void init_const_signed(ConstExprValue *const_val, TypeTableEntry *type, int64_t |
| 3533 | } | 3533 | } |
| 3534 | 3534 | ||
| 3535 | ConstExprValue *create_const_signed(TypeTableEntry *type, int64_t x) { | 3535 | ConstExprValue *create_const_signed(TypeTableEntry *type, int64_t x) { |
| 3536 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | 3536 | ConstExprValue *const_val = create_const_vals(1); |
| 3537 | init_const_signed(const_val, type, x); | 3537 | init_const_signed(const_val, type, x); |
| 3538 | return const_val; | 3538 | return const_val; |
| 3539 | } | 3539 | } |
| ... | @@ -3545,7 +3545,7 @@ void init_const_float(ConstExprValue *const_val, TypeTableEntry *type, double va | ... | @@ -3545,7 +3545,7 @@ void init_const_float(ConstExprValue *const_val, TypeTableEntry *type, double va |
| 3545 | } | 3545 | } |
| 3546 | 3546 | ||
| 3547 | ConstExprValue *create_const_float(TypeTableEntry *type, double value) { | 3547 | ConstExprValue *create_const_float(TypeTableEntry *type, double value) { |
| 3548 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | 3548 | ConstExprValue *const_val = create_const_vals(1); |
| 3549 | init_const_float(const_val, type, value); | 3549 | init_const_float(const_val, type, value); |
| 3550 | return const_val; | 3550 | return const_val; |
| 3551 | } | 3551 | } |
| ... | @@ -3557,7 +3557,7 @@ void init_const_enum_tag(ConstExprValue *const_val, TypeTableEntry *type, uint64 | ... | @@ -3557,7 +3557,7 @@ void init_const_enum_tag(ConstExprValue *const_val, TypeTableEntry *type, uint64 |
| 3557 | } | 3557 | } |
| 3558 | 3558 | ||
| 3559 | ConstExprValue *create_const_enum_tag(TypeTableEntry *type, uint64_t tag) { | 3559 | ConstExprValue *create_const_enum_tag(TypeTableEntry *type, uint64_t tag) { |
| 3560 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | 3560 | ConstExprValue *const_val = create_const_vals(1); |
| 3561 | init_const_enum_tag(const_val, type, tag); | 3561 | init_const_enum_tag(const_val, type, tag); |
| 3562 | return const_val; | 3562 | return const_val; |
| 3563 | } | 3563 | } |
| ... | @@ -3569,7 +3569,7 @@ void init_const_bool(CodeGen *g, ConstExprValue *const_val, bool value) { | ... | @@ -3569,7 +3569,7 @@ void init_const_bool(CodeGen *g, ConstExprValue *const_val, bool value) { |
| 3569 | } | 3569 | } |
| 3570 | 3570 | ||
| 3571 | ConstExprValue *create_const_bool(CodeGen *g, bool value) { | 3571 | ConstExprValue *create_const_bool(CodeGen *g, bool value) { |
| 3572 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | 3572 | ConstExprValue *const_val = create_const_vals(1); |
| 3573 | init_const_bool(g, const_val, value); | 3573 | init_const_bool(g, const_val, value); |
| 3574 | return const_val; | 3574 | return const_val; |
| 3575 | } | 3575 | } |
| ... | @@ -3580,7 +3580,7 @@ void init_const_runtime(ConstExprValue *const_val, TypeTableEntry *type) { | ... | @@ -3580,7 +3580,7 @@ void init_const_runtime(ConstExprValue *const_val, TypeTableEntry *type) { |
| 3580 | } | 3580 | } |
| 3581 | 3581 | ||
| 3582 | ConstExprValue *create_const_runtime(TypeTableEntry *type) { | 3582 | ConstExprValue *create_const_runtime(TypeTableEntry *type) { |
| 3583 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | 3583 | ConstExprValue *const_val = create_const_vals(1); |
| 3584 | init_const_runtime(const_val, type); | 3584 | init_const_runtime(const_val, type); |
| 3585 | return const_val; | 3585 | return const_val; |
| 3586 | } | 3586 | } |
| ... | @@ -3592,7 +3592,7 @@ void init_const_type(CodeGen *g, ConstExprValue *const_val, TypeTableEntry *type | ... | @@ -3592,7 +3592,7 @@ void init_const_type(CodeGen *g, ConstExprValue *const_val, TypeTableEntry *type |
| 3592 | } | 3592 | } |
| 3593 | 3593 | ||
| 3594 | ConstExprValue *create_const_type(CodeGen *g, TypeTableEntry *type_value) { | 3594 | ConstExprValue *create_const_type(CodeGen *g, TypeTableEntry *type_value) { |
| 3595 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | 3595 | ConstExprValue *const_val = create_const_vals(1); |
| 3596 | init_const_type(g, const_val, type_value); | 3596 | init_const_type(g, const_val, type_value); |
| 3597 | return const_val; | 3597 | return const_val; |
| 3598 | } | 3598 | } |
| ... | @@ -3604,14 +3604,14 @@ void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *arr | ... | @@ -3604,14 +3604,14 @@ void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *arr |
| 3604 | 3604 | ||
| 3605 | const_val->special = ConstValSpecialStatic; | 3605 | const_val->special = ConstValSpecialStatic; |
| 3606 | const_val->type = get_slice_type(g, array_val->type->data.array.child_type, is_const); | 3606 | const_val->type = get_slice_type(g, array_val->type->data.array.child_type, is_const); |
| 3607 | const_val->data.x_struct.fields = allocate<ConstExprValue>(2); | 3607 | const_val->data.x_struct.fields = create_const_vals(2); |
| 3608 | 3608 | ||
| 3609 | init_const_ptr_array(g, &const_val->data.x_struct.fields[slice_ptr_index], array_val, start, is_const); | 3609 | init_const_ptr_array(g, &const_val->data.x_struct.fields[slice_ptr_index], array_val, start, is_const); |
| 3610 | init_const_usize(g, &const_val->data.x_struct.fields[slice_len_index], len); | 3610 | init_const_usize(g, &const_val->data.x_struct.fields[slice_len_index], len); |
| 3611 | } | 3611 | } |
| 3612 | 3612 | ||
| 3613 | ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t start, size_t len, bool is_const) { | 3613 | ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t start, size_t len, bool is_const) { |
| 3614 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | 3614 | ConstExprValue *const_val = create_const_vals(1); |
| 3615 | init_const_slice(g, const_val, array_val, start, len, is_const); | 3615 | init_const_slice(g, const_val, array_val, start, len, is_const); |
| 3616 | return const_val; | 3616 | return const_val; |
| 3617 | } | 3617 | } |
| ... | @@ -3630,7 +3630,7 @@ void init_const_ptr_array(CodeGen *g, ConstExprValue *const_val, ConstExprValue | ... | @@ -3630,7 +3630,7 @@ void init_const_ptr_array(CodeGen *g, ConstExprValue *const_val, ConstExprValue |
| 3630 | } | 3630 | } |
| 3631 | 3631 | ||
| 3632 | ConstExprValue *create_const_ptr_array(CodeGen *g, ConstExprValue *array_val, size_t elem_index, bool is_const) { | 3632 | ConstExprValue *create_const_ptr_array(CodeGen *g, ConstExprValue *array_val, size_t elem_index, bool is_const) { |
| 3633 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | 3633 | ConstExprValue *const_val = create_const_vals(1); |
| 3634 | init_const_ptr_array(g, const_val, array_val, elem_index, is_const); | 3634 | init_const_ptr_array(g, const_val, array_val, elem_index, is_const); |
| 3635 | return const_val; | 3635 | return const_val; |
| 3636 | } | 3636 | } |
| ... | @@ -3643,7 +3643,7 @@ void init_const_ptr_ref(CodeGen *g, ConstExprValue *const_val, ConstExprValue *p | ... | @@ -3643,7 +3643,7 @@ void init_const_ptr_ref(CodeGen *g, ConstExprValue *const_val, ConstExprValue *p |
| 3643 | } | 3643 | } |
| 3644 | 3644 | ||
| 3645 | ConstExprValue *create_const_ptr_ref(CodeGen *g, ConstExprValue *pointee_val, bool is_const) { | 3645 | ConstExprValue *create_const_ptr_ref(CodeGen *g, ConstExprValue *pointee_val, bool is_const) { |
| 3646 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | 3646 | ConstExprValue *const_val = create_const_vals(1); |
| 3647 | init_const_ptr_ref(g, const_val, pointee_val, is_const); | 3647 | init_const_ptr_ref(g, const_val, pointee_val, is_const); |
| 3648 | return const_val; | 3648 | return const_val; |
| 3649 | } | 3649 | } |
| ... | @@ -3660,7 +3660,7 @@ void init_const_ptr_hard_coded_addr(CodeGen *g, ConstExprValue *const_val, TypeT | ... | @@ -3660,7 +3660,7 @@ void init_const_ptr_hard_coded_addr(CodeGen *g, ConstExprValue *const_val, TypeT |
| 3660 | ConstExprValue *create_const_ptr_hard_coded_addr(CodeGen *g, TypeTableEntry *pointee_type, | 3660 | ConstExprValue *create_const_ptr_hard_coded_addr(CodeGen *g, TypeTableEntry *pointee_type, |
| 3661 | size_t addr, bool is_const) | 3661 | size_t addr, bool is_const) |
| 3662 | { | 3662 | { |
| 3663 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | 3663 | ConstExprValue *const_val = create_const_vals(1); |
| 3664 | init_const_ptr_hard_coded_addr(g, const_val, pointee_type, addr, is_const); | 3664 | init_const_ptr_hard_coded_addr(g, const_val, pointee_type, addr, is_const); |
| 3665 | return const_val; | 3665 | return const_val; |
| 3666 | } | 3666 | } |
| ... | @@ -3673,7 +3673,7 @@ void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_inde | ... | @@ -3673,7 +3673,7 @@ void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_inde |
| 3673 | } | 3673 | } |
| 3674 | 3674 | ||
| 3675 | ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end) { | 3675 | ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end) { |
| 3676 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | 3676 | ConstExprValue *const_val = create_const_vals(1); |
| 3677 | init_const_arg_tuple(g, const_val, arg_index_start, arg_index_end); | 3677 | init_const_arg_tuple(g, const_val, arg_index_start, arg_index_end); |
| 3678 | return const_val; | 3678 | return const_val; |
| 3679 | } | 3679 | } |
| ... | @@ -3689,7 +3689,7 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) { | ... | @@ -3689,7 +3689,7 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) { |
| 3689 | 3689 | ||
| 3690 | const_val->special = ConstValSpecialStatic; | 3690 | const_val->special = ConstValSpecialStatic; |
| 3691 | size_t field_count = wanted_type->data.structure.src_field_count; | 3691 | size_t field_count = wanted_type->data.structure.src_field_count; |
| 3692 | const_val->data.x_struct.fields = allocate<ConstExprValue>(field_count); | 3692 | const_val->data.x_struct.fields = create_const_vals(field_count); |
| 3693 | for (size_t i = 0; i < field_count; i += 1) { | 3693 | for (size_t i = 0; i < field_count; i += 1) { |
| 3694 | ConstExprValue *field_val = &const_val->data.x_struct.fields[i]; | 3694 | ConstExprValue *field_val = &const_val->data.x_struct.fields[i]; |
| 3695 | field_val->type = wanted_type->data.structure.fields[i].type_entry; | 3695 | field_val->type = wanted_type->data.structure.fields[i].type_entry; |
| ... | @@ -3707,6 +3707,15 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) { | ... | @@ -3707,6 +3707,15 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) { |
| 3707 | } | 3707 | } |
| 3708 | } | 3708 | } |
| 3709 | 3709 | ||
| 3710 | ConstExprValue *create_const_vals(size_t count) { | ||
| 3711 | ConstGlobalRefs *global_refs = allocate<ConstGlobalRefs>(count); | ||
| 3712 | ConstExprValue *vals = allocate<ConstExprValue>(count); | ||
| 3713 | for (size_t i = 0; i < count; i += 1) { | ||
| 3714 | vals[i].global_refs = &global_refs[i]; | ||
| 3715 | } | ||
| 3716 | return vals; | ||
| 3717 | } | ||
| 3718 | |||
| 3710 | void ensure_complete_type(CodeGen *g, TypeTableEntry *type_entry) { | 3719 | void ensure_complete_type(CodeGen *g, TypeTableEntry *type_entry) { |
| 3711 | if (type_entry->id == TypeTableEntryIdStruct) { | 3720 | if (type_entry->id == TypeTableEntryIdStruct) { |
| 3712 | if (!type_entry->data.structure.complete) | 3721 | if (!type_entry->data.structure.complete) |
| ... | @@ -3788,16 +3797,24 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) { | ... | @@ -3788,16 +3797,24 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) { |
| 3788 | return false; | 3797 | return false; |
| 3789 | return true; | 3798 | return true; |
| 3790 | case ConstPtrSpecialBaseArray: | 3799 | case ConstPtrSpecialBaseArray: |
| 3791 | if (a->data.x_ptr.data.base_array.array_val != b->data.x_ptr.data.base_array.array_val) | 3800 | if (a->data.x_ptr.data.base_array.array_val != b->data.x_ptr.data.base_array.array_val && |
| 3801 | a->data.x_ptr.data.base_array.array_val->global_refs != | ||
| 3802 | b->data.x_ptr.data.base_array.array_val->global_refs) | ||
| 3803 | { | ||
| 3792 | return false; | 3804 | return false; |
| 3805 | } | ||
| 3793 | if (a->data.x_ptr.data.base_array.elem_index != b->data.x_ptr.data.base_array.elem_index) | 3806 | if (a->data.x_ptr.data.base_array.elem_index != b->data.x_ptr.data.base_array.elem_index) |
| 3794 | return false; | 3807 | return false; |
| 3795 | if (a->data.x_ptr.data.base_array.is_cstr != b->data.x_ptr.data.base_array.is_cstr) | 3808 | if (a->data.x_ptr.data.base_array.is_cstr != b->data.x_ptr.data.base_array.is_cstr) |
| 3796 | return false; | 3809 | return false; |
| 3797 | return true; | 3810 | return true; |
| 3798 | case ConstPtrSpecialBaseStruct: | 3811 | case ConstPtrSpecialBaseStruct: |
| 3799 | if (a->data.x_ptr.data.base_struct.struct_val != b->data.x_ptr.data.base_struct.struct_val) | 3812 | if (a->data.x_ptr.data.base_struct.struct_val != b->data.x_ptr.data.base_struct.struct_val && |
| 3813 | a->data.x_ptr.data.base_struct.struct_val->global_refs != | ||
| 3814 | b->data.x_ptr.data.base_struct.struct_val->global_refs) | ||
| 3815 | { | ||
| 3800 | return false; | 3816 | return false; |
| 3817 | } | ||
| 3801 | if (a->data.x_ptr.data.base_struct.field_index != b->data.x_ptr.data.base_struct.field_index) | 3818 | if (a->data.x_ptr.data.base_struct.field_index != b->data.x_ptr.data.base_struct.field_index) |
| 3802 | return false; | 3819 | return false; |
| 3803 | return true; | 3820 | return true; |
| ... | @@ -4293,7 +4310,7 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) { | ... | @@ -4293,7 +4310,7 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) { |
| 4293 | if (const_val->data.x_array.special == ConstArraySpecialUndef) { | 4310 | if (const_val->data.x_array.special == ConstArraySpecialUndef) { |
| 4294 | const_val->data.x_array.special = ConstArraySpecialNone; | 4311 | const_val->data.x_array.special = ConstArraySpecialNone; |
| 4295 | size_t elem_count = const_val->type->data.array.len; | 4312 | size_t elem_count = const_val->type->data.array.len; |
| 4296 | const_val->data.x_array.s_none.elements = allocate<ConstExprValue>(elem_count); | 4313 | const_val->data.x_array.s_none.elements = create_const_vals(elem_count); |
| 4297 | for (size_t i = 0; i < elem_count; i += 1) { | 4314 | for (size_t i = 0; i < elem_count; i += 1) { |
| 4298 | ConstExprValue *element_val = &const_val->data.x_array.s_none.elements[i]; | 4315 | ConstExprValue *element_val = &const_val->data.x_array.s_none.elements[i]; |
| 4299 | element_val->type = const_val->type->data.array.child_type; | 4316 | element_val->type = const_val->type->data.array.child_type; |
src/analyze.hpp+2| ... | @@ -153,6 +153,8 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_ | ... | @@ -153,6 +153,8 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_ |
| 153 | 153 | ||
| 154 | void init_const_undefined(CodeGen *g, ConstExprValue *const_val); | 154 | void init_const_undefined(CodeGen *g, ConstExprValue *const_val); |
| 155 | 155 | ||
| 156 | ConstExprValue *create_const_vals(size_t count); | ||
| 157 | |||
| 156 | TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits); | 158 | TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits); |
| 157 | ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value); | 159 | ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value); |
| 158 | FnTableEntry *get_extern_panic_fn(CodeGen *g); | 160 | FnTableEntry *get_extern_panic_fn(CodeGen *g); |
src/codegen.cpp+47-32| ... | @@ -682,8 +682,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) { | ... | @@ -682,8 +682,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) { |
| 682 | 682 | ||
| 683 | static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) { | 683 | static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) { |
| 684 | ConstExprValue *val = &g->panic_msg_vals[msg_id]; | 684 | ConstExprValue *val = &g->panic_msg_vals[msg_id]; |
| 685 | if (val->llvm_global) | 685 | if (val->global_refs->llvm_global) |
| 686 | return val->llvm_global; | 686 | return val->global_refs->llvm_global; |
| 687 | 687 | ||
| 688 | Buf *buf_msg = panic_msg_buf(msg_id); | 688 | Buf *buf_msg = panic_msg_buf(msg_id); |
| 689 | ConstExprValue *array_val = create_const_str_lit(g, buf_msg); | 689 | ConstExprValue *array_val = create_const_str_lit(g, buf_msg); |
| ... | @@ -692,8 +692,8 @@ static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) { | ... | @@ -692,8 +692,8 @@ static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) { |
| 692 | render_const_val_global(g, val, ""); | 692 | render_const_val_global(g, val, ""); |
| 693 | render_const_val(g, val); | 693 | render_const_val(g, val); |
| 694 | 694 | ||
| 695 | assert(val->llvm_global); | 695 | assert(val->global_refs->llvm_global); |
| 696 | return val->llvm_global; | 696 | return val->global_refs->llvm_global; |
| 697 | } | 697 | } |
| 698 | 698 | ||
| 699 | static void gen_panic_raw(CodeGen *g, LLVMValueRef msg_ptr, LLVMValueRef msg_len) { | 699 | static void gen_panic_raw(CodeGen *g, LLVMValueRef msg_ptr, LLVMValueRef msg_len) { |
| ... | @@ -1086,11 +1086,11 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) { | ... | @@ -1086,11 +1086,11 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) { |
| 1086 | if (handle_is_ptr(instruction->value.type)) { | 1086 | if (handle_is_ptr(instruction->value.type)) { |
| 1087 | render_const_val_global(g, &instruction->value, ""); | 1087 | render_const_val_global(g, &instruction->value, ""); |
| 1088 | TypeTableEntry *ptr_type = get_pointer_to_type(g, instruction->value.type, true); | 1088 | TypeTableEntry *ptr_type = get_pointer_to_type(g, instruction->value.type, true); |
| 1089 | instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.llvm_global, ptr_type->type_ref, ""); | 1089 | instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_global, ptr_type->type_ref, ""); |
| 1090 | } else if (instruction->value.type->id == TypeTableEntryIdPointer) { | 1090 | } else if (instruction->value.type->id == TypeTableEntryIdPointer) { |
| 1091 | instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.llvm_value, instruction->value.type->type_ref, ""); | 1091 | instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_value, instruction->value.type->type_ref, ""); |
| 1092 | } else { | 1092 | } else { |
| 1093 | instruction->llvm_value = instruction->value.llvm_value; | 1093 | instruction->llvm_value = instruction->value.global_refs->llvm_value; |
| 1094 | } | 1094 | } |
| 1095 | assert(instruction->llvm_value); | 1095 | assert(instruction->llvm_value); |
| 1096 | } | 1096 | } |
| ... | @@ -1535,6 +1535,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, | ... | @@ -1535,6 +1535,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, |
| 1535 | 1535 | ||
| 1536 | switch (cast_instruction->cast_op) { | 1536 | switch (cast_instruction->cast_op) { |
| 1537 | case CastOpNoCast: | 1537 | case CastOpNoCast: |
| 1538 | case CastOpNumLitToConcrete: | ||
| 1538 | zig_unreachable(); | 1539 | zig_unreachable(); |
| 1539 | case CastOpNoop: | 1540 | case CastOpNoop: |
| 1540 | return expr_val; | 1541 | return expr_val; |
| ... | @@ -3197,7 +3198,7 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent | ... | @@ -3197,7 +3198,7 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent |
| 3197 | case ConstParentIdNone: | 3198 | case ConstParentIdNone: |
| 3198 | render_const_val(g, val); | 3199 | render_const_val(g, val); |
| 3199 | render_const_val_global(g, val, ""); | 3200 | render_const_val_global(g, val, ""); |
| 3200 | return val->llvm_global; | 3201 | return val->global_refs->llvm_global; |
| 3201 | case ConstParentIdStruct: | 3202 | case ConstParentIdStruct: |
| 3202 | return gen_const_ptr_struct_recursive(g, parent->data.p_struct.struct_val, | 3203 | return gen_const_ptr_struct_recursive(g, parent->data.p_struct.struct_val, |
| 3203 | parent->data.p_struct.field_index); | 3204 | parent->data.p_struct.field_index); |
| ... | @@ -3506,9 +3507,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { | ... | @@ -3506,9 +3507,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3506 | render_const_val(g, pointee); | 3507 | render_const_val(g, pointee); |
| 3507 | render_const_val_global(g, pointee, ""); | 3508 | render_const_val_global(g, pointee, ""); |
| 3508 | ConstExprValue *other_val = pointee; | 3509 | ConstExprValue *other_val = pointee; |
| 3509 | const_val->llvm_value = LLVMConstBitCast(other_val->llvm_global, const_val->type->type_ref); | 3510 | const_val->global_refs->llvm_value = LLVMConstBitCast(other_val->global_refs->llvm_global, const_val->type->type_ref); |
| 3510 | render_const_val_global(g, const_val, ""); | 3511 | render_const_val_global(g, const_val, ""); |
| 3511 | return const_val->llvm_value; | 3512 | return const_val->global_refs->llvm_value; |
| 3512 | } | 3513 | } |
| 3513 | case ConstPtrSpecialBaseArray: | 3514 | case ConstPtrSpecialBaseArray: |
| 3514 | { | 3515 | { |
| ... | @@ -3518,15 +3519,15 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { | ... | @@ -3518,15 +3519,15 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3518 | if (array_const_val->type->zero_bits) { | 3519 | if (array_const_val->type->zero_bits) { |
| 3519 | // make this a null pointer | 3520 | // make this a null pointer |
| 3520 | TypeTableEntry *usize = g->builtin_types.entry_usize; | 3521 | TypeTableEntry *usize = g->builtin_types.entry_usize; |
| 3521 | const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref), | 3522 | const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref), |
| 3522 | const_val->type->type_ref); | 3523 | const_val->type->type_ref); |
| 3523 | render_const_val_global(g, const_val, ""); | 3524 | render_const_val_global(g, const_val, ""); |
| 3524 | return const_val->llvm_value; | 3525 | return const_val->global_refs->llvm_value; |
| 3525 | } | 3526 | } |
| 3526 | LLVMValueRef uncasted_ptr_val = gen_const_ptr_array_recursive(g, array_const_val, | 3527 | LLVMValueRef uncasted_ptr_val = gen_const_ptr_array_recursive(g, array_const_val, |
| 3527 | elem_index); | 3528 | elem_index); |
| 3528 | LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref); | 3529 | LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref); |
| 3529 | const_val->llvm_value = ptr_val; | 3530 | const_val->global_refs->llvm_value = ptr_val; |
| 3530 | render_const_val_global(g, const_val, ""); | 3531 | render_const_val_global(g, const_val, ""); |
| 3531 | return ptr_val; | 3532 | return ptr_val; |
| 3532 | } | 3533 | } |
| ... | @@ -3537,10 +3538,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { | ... | @@ -3537,10 +3538,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3537 | if (struct_const_val->type->zero_bits) { | 3538 | if (struct_const_val->type->zero_bits) { |
| 3538 | // make this a null pointer | 3539 | // make this a null pointer |
| 3539 | TypeTableEntry *usize = g->builtin_types.entry_usize; | 3540 | TypeTableEntry *usize = g->builtin_types.entry_usize; |
| 3540 | const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref), | 3541 | const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref), |
| 3541 | const_val->type->type_ref); | 3542 | const_val->type->type_ref); |
| 3542 | render_const_val_global(g, const_val, ""); | 3543 | render_const_val_global(g, const_val, ""); |
| 3543 | return const_val->llvm_value; | 3544 | return const_val->global_refs->llvm_value; |
| 3544 | } | 3545 | } |
| 3545 | size_t src_field_index = const_val->data.x_ptr.data.base_struct.field_index; | 3546 | size_t src_field_index = const_val->data.x_ptr.data.base_struct.field_index; |
| 3546 | size_t gen_field_index = | 3547 | size_t gen_field_index = |
| ... | @@ -3548,7 +3549,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { | ... | @@ -3548,7 +3549,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3548 | LLVMValueRef uncasted_ptr_val = gen_const_ptr_struct_recursive(g, struct_const_val, | 3549 | LLVMValueRef uncasted_ptr_val = gen_const_ptr_struct_recursive(g, struct_const_val, |
| 3549 | gen_field_index); | 3550 | gen_field_index); |
| 3550 | LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref); | 3551 | LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref); |
| 3551 | const_val->llvm_value = ptr_val; | 3552 | const_val->global_refs->llvm_value = ptr_val; |
| 3552 | render_const_val_global(g, const_val, ""); | 3553 | render_const_val_global(g, const_val, ""); |
| 3553 | return ptr_val; | 3554 | return ptr_val; |
| 3554 | } | 3555 | } |
| ... | @@ -3556,10 +3557,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { | ... | @@ -3556,10 +3557,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3556 | { | 3557 | { |
| 3557 | uint64_t addr_value = const_val->data.x_ptr.data.hard_coded_addr.addr; | 3558 | uint64_t addr_value = const_val->data.x_ptr.data.hard_coded_addr.addr; |
| 3558 | TypeTableEntry *usize = g->builtin_types.entry_usize; | 3559 | TypeTableEntry *usize = g->builtin_types.entry_usize; |
| 3559 | const_val->llvm_value = LLVMConstIntToPtr(LLVMConstInt(usize->type_ref, addr_value, false), | 3560 | const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstInt(usize->type_ref, addr_value, false), |
| 3560 | const_val->type->type_ref); | 3561 | const_val->type->type_ref); |
| 3561 | render_const_val_global(g, const_val, ""); | 3562 | render_const_val_global(g, const_val, ""); |
| 3562 | return const_val->llvm_value; | 3563 | return const_val->global_refs->llvm_value; |
| 3563 | } | 3564 | } |
| 3564 | } | 3565 | } |
| 3565 | } | 3566 | } |
| ... | @@ -3608,27 +3609,32 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { | ... | @@ -3608,27 +3609,32 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3608 | } | 3609 | } |
| 3609 | 3610 | ||
| 3610 | static void render_const_val(CodeGen *g, ConstExprValue *const_val) { | 3611 | static void render_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3611 | if (!const_val->llvm_value) | 3612 | if (!const_val->global_refs) |
| 3612 | const_val->llvm_value = gen_const_val(g, const_val); | 3613 | const_val->global_refs = allocate<ConstGlobalRefs>(1); |
| 3614 | if (!const_val->global_refs->llvm_value) | ||
| 3615 | const_val->global_refs->llvm_value = gen_const_val(g, const_val); | ||
| 3613 | 3616 | ||
| 3614 | if (const_val->llvm_global) | 3617 | if (const_val->global_refs->llvm_global) |
| 3615 | LLVMSetInitializer(const_val->llvm_global, const_val->llvm_value); | 3618 | LLVMSetInitializer(const_val->global_refs->llvm_global, const_val->global_refs->llvm_value); |
| 3616 | } | 3619 | } |
| 3617 | 3620 | ||
| 3618 | static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const char *name) { | 3621 | static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const char *name) { |
| 3619 | if (!const_val->llvm_global) { | 3622 | if (!const_val->global_refs) |
| 3620 | LLVMTypeRef type_ref = const_val->llvm_value ? LLVMTypeOf(const_val->llvm_value) : const_val->type->type_ref; | 3623 | const_val->global_refs = allocate<ConstGlobalRefs>(1); |
| 3624 | |||
| 3625 | if (!const_val->global_refs->llvm_global) { | ||
| 3626 | LLVMTypeRef type_ref = const_val->global_refs->llvm_value ? LLVMTypeOf(const_val->global_refs->llvm_value) : const_val->type->type_ref; | ||
| 3621 | LLVMValueRef global_value = LLVMAddGlobal(g->module, type_ref, name); | 3627 | LLVMValueRef global_value = LLVMAddGlobal(g->module, type_ref, name); |
| 3622 | LLVMSetLinkage(global_value, LLVMInternalLinkage); | 3628 | LLVMSetLinkage(global_value, LLVMInternalLinkage); |
| 3623 | LLVMSetGlobalConstant(global_value, true); | 3629 | LLVMSetGlobalConstant(global_value, true); |
| 3624 | LLVMSetUnnamedAddr(global_value, true); | 3630 | LLVMSetUnnamedAddr(global_value, true); |
| 3625 | LLVMSetAlignment(global_value, get_type_alignment(g, const_val->type)); | 3631 | LLVMSetAlignment(global_value, get_type_alignment(g, const_val->type)); |
| 3626 | 3632 | ||
| 3627 | const_val->llvm_global = global_value; | 3633 | const_val->global_refs->llvm_global = global_value; |
| 3628 | } | 3634 | } |
| 3629 | 3635 | ||
| 3630 | if (const_val->llvm_value) | 3636 | if (const_val->global_refs->llvm_value) |
| 3631 | LLVMSetInitializer(const_val->llvm_global, const_val->llvm_value); | 3637 | LLVMSetInitializer(const_val->global_refs->llvm_global, const_val->global_refs->llvm_value); |
| 3632 | } | 3638 | } |
| 3633 | 3639 | ||
| 3634 | static void delete_unused_builtin_fns(CodeGen *g) { | 3640 | static void delete_unused_builtin_fns(CodeGen *g) { |
| ... | @@ -3849,7 +3855,7 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -3849,7 +3855,7 @@ static void do_code_gen(CodeGen *g) { |
| 3849 | bool exported = (var->linkage == VarLinkageExport); | 3855 | bool exported = (var->linkage == VarLinkageExport); |
| 3850 | render_const_val(g, var->value); | 3856 | render_const_val(g, var->value); |
| 3851 | render_const_val_global(g, var->value, buf_ptr(get_mangled_name(g, &var->name, exported))); | 3857 | render_const_val_global(g, var->value, buf_ptr(get_mangled_name(g, &var->name, exported))); |
| 3852 | global_value = var->value->llvm_global; | 3858 | global_value = var->value->global_refs->llvm_global; |
| 3853 | 3859 | ||
| 3854 | if (exported) { | 3860 | if (exported) { |
| 3855 | LLVMSetLinkage(global_value, LLVMExternalLinkage); | 3861 | LLVMSetLinkage(global_value, LLVMExternalLinkage); |
| ... | @@ -3862,7 +3868,7 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -3862,7 +3868,7 @@ static void do_code_gen(CodeGen *g) { |
| 3862 | 3868 | ||
| 3863 | // TODO debug info for function pointers | 3869 | // TODO debug info for function pointers |
| 3864 | if (var->gen_is_const && var->value->type->id != TypeTableEntryIdFn) { | 3870 | if (var->gen_is_const && var->value->type->id != TypeTableEntryIdFn) { |
| 3865 | gen_global_var(g, var, var->value->llvm_value, var->value->type); | 3871 | gen_global_var(g, var, var->value->global_refs->llvm_value, var->value->type); |
| 3866 | } | 3872 | } |
| 3867 | } | 3873 | } |
| 3868 | 3874 | ||
| ... | @@ -4737,9 +4743,18 @@ static void init(CodeGen *g) { | ... | @@ -4737,9 +4743,18 @@ static void init(CodeGen *g) { |
| 4737 | 4743 | ||
| 4738 | g->invalid_instruction = allocate<IrInstruction>(1); | 4744 | g->invalid_instruction = allocate<IrInstruction>(1); |
| 4739 | g->invalid_instruction->value.type = g->builtin_types.entry_invalid; | 4745 | g->invalid_instruction->value.type = g->builtin_types.entry_invalid; |
| 4746 | g->invalid_instruction->value.global_refs = allocate<ConstGlobalRefs>(1); | ||
| 4740 | 4747 | ||
| 4741 | g->const_void_val.special = ConstValSpecialStatic; | 4748 | g->const_void_val.special = ConstValSpecialStatic; |
| 4742 | g->const_void_val.type = g->builtin_types.entry_void; | 4749 | g->const_void_val.type = g->builtin_types.entry_void; |
| 4750 | g->const_void_val.global_refs = allocate<ConstGlobalRefs>(1); | ||
| 4751 | |||
| 4752 | { | ||
| 4753 | ConstGlobalRefs *global_refs = allocate<ConstGlobalRefs>(PanicMsgIdCount); | ||
| 4754 | for (size_t i = 0; i < PanicMsgIdCount; i += 1) { | ||
| 4755 | g->panic_msg_vals[i].global_refs = &global_refs[i]; | ||
| 4756 | } | ||
| 4757 | } | ||
| 4743 | 4758 | ||
| 4744 | define_builtin_fns(g); | 4759 | define_builtin_fns(g); |
| 4745 | define_builtin_compile_vars(g); | 4760 | define_builtin_compile_vars(g); |
| ... | @@ -4826,10 +4841,10 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) { | ... | @@ -4826,10 +4841,10 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) { |
| 4826 | TypeTableEntry *field_types[] = { str_type, fn_type, }; | 4841 | TypeTableEntry *field_types[] = { str_type, fn_type, }; |
| 4827 | TypeTableEntry *struct_type = get_struct_type(g, "ZigTestFn", field_names, field_types, 2); | 4842 | TypeTableEntry *struct_type = get_struct_type(g, "ZigTestFn", field_names, field_types, 2); |
| 4828 | 4843 | ||
| 4829 | ConstExprValue *test_fn_array = allocate<ConstExprValue>(1); | 4844 | ConstExprValue *test_fn_array = create_const_vals(1); |
| 4830 | test_fn_array->type = get_array_type(g, struct_type, g->test_fns.length); | 4845 | test_fn_array->type = get_array_type(g, struct_type, g->test_fns.length); |
| 4831 | test_fn_array->special = ConstValSpecialStatic; | 4846 | test_fn_array->special = ConstValSpecialStatic; |
| 4832 | test_fn_array->data.x_array.s_none.elements = allocate<ConstExprValue>(g->test_fns.length); | 4847 | test_fn_array->data.x_array.s_none.elements = create_const_vals(g->test_fns.length); |
| 4833 | 4848 | ||
| 4834 | for (size_t i = 0; i < g->test_fns.length; i += 1) { | 4849 | for (size_t i = 0; i < g->test_fns.length; i += 1) { |
| 4835 | FnTableEntry *test_fn_entry = g->test_fns.at(i); | 4850 | FnTableEntry *test_fn_entry = g->test_fns.at(i); |
| ... | @@ -4840,7 +4855,7 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) { | ... | @@ -4840,7 +4855,7 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) { |
| 4840 | this_val->data.x_struct.parent.id = ConstParentIdArray; | 4855 | this_val->data.x_struct.parent.id = ConstParentIdArray; |
| 4841 | this_val->data.x_struct.parent.data.p_array.array_val = test_fn_array; | 4856 | this_val->data.x_struct.parent.data.p_array.array_val = test_fn_array; |
| 4842 | this_val->data.x_struct.parent.data.p_array.elem_index = i; | 4857 | this_val->data.x_struct.parent.data.p_array.elem_index = i; |
| 4843 | this_val->data.x_struct.fields = allocate<ConstExprValue>(2); | 4858 | this_val->data.x_struct.fields = create_const_vals(2); |
| 4844 | 4859 | ||
| 4845 | ConstExprValue *name_field = &this_val->data.x_struct.fields[0]; | 4860 | ConstExprValue *name_field = &this_val->data.x_struct.fields[0]; |
| 4846 | ConstExprValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name); | 4861 | ConstExprValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name); |
src/ir.cpp+39-24| ... | @@ -553,6 +553,7 @@ static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_no | ... | @@ -553,6 +553,7 @@ static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_no |
| 553 | special_instruction->base.source_node = source_node; | 553 | special_instruction->base.source_node = source_node; |
| 554 | special_instruction->base.debug_id = exec_next_debug_id(irb->exec); | 554 | special_instruction->base.debug_id = exec_next_debug_id(irb->exec); |
| 555 | special_instruction->base.owner_bb = irb->current_basic_block; | 555 | special_instruction->base.owner_bb = irb->current_basic_block; |
| 556 | special_instruction->base.value.global_refs = allocate<ConstGlobalRefs>(1); | ||
| 556 | return special_instruction; | 557 | return special_instruction; |
| 557 | } | 558 | } |
| 558 | 559 | ||
| ... | @@ -3210,7 +3211,7 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco | ... | @@ -3210,7 +3211,7 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco |
| 3210 | variable_entry->mem_slot_index = SIZE_MAX; | 3211 | variable_entry->mem_slot_index = SIZE_MAX; |
| 3211 | variable_entry->is_comptime = is_comptime; | 3212 | variable_entry->is_comptime = is_comptime; |
| 3212 | variable_entry->src_arg_index = SIZE_MAX; | 3213 | variable_entry->src_arg_index = SIZE_MAX; |
| 3213 | variable_entry->value = allocate<ConstExprValue>(1); | 3214 | variable_entry->value = create_const_vals(1); |
| 3214 | 3215 | ||
| 3215 | if (name) { | 3216 | if (name) { |
| 3216 | buf_init_from_buf(&variable_entry->name, name); | 3217 | buf_init_from_buf(&variable_entry->name, name); |
| ... | @@ -6565,6 +6566,14 @@ static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, TypeTableE | ... | @@ -6565,6 +6566,14 @@ static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, TypeTableE |
| 6565 | } | 6566 | } |
| 6566 | } | 6567 | } |
| 6567 | 6568 | ||
| 6569 | static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) { | ||
| 6570 | ConstGlobalRefs *global_refs = dest->global_refs; | ||
| 6571 | *dest = *src; | ||
| 6572 | if (!same_global_refs) { | ||
| 6573 | dest->global_refs = global_refs; | ||
| 6574 | } | ||
| 6575 | } | ||
| 6576 | |||
| 6568 | static void eval_const_expr_implicit_cast(CastOp cast_op, | 6577 | static void eval_const_expr_implicit_cast(CastOp cast_op, |
| 6569 | ConstExprValue *other_val, TypeTableEntry *other_type, | 6578 | ConstExprValue *other_val, TypeTableEntry *other_type, |
| 6570 | ConstExprValue *const_val, TypeTableEntry *new_type) | 6579 | ConstExprValue *const_val, TypeTableEntry *new_type) |
| ... | @@ -6576,7 +6585,13 @@ static void eval_const_expr_implicit_cast(CastOp cast_op, | ... | @@ -6576,7 +6585,13 @@ static void eval_const_expr_implicit_cast(CastOp cast_op, |
| 6576 | case CastOpNoCast: | 6585 | case CastOpNoCast: |
| 6577 | zig_unreachable(); | 6586 | zig_unreachable(); |
| 6578 | case CastOpNoop: | 6587 | case CastOpNoop: |
| 6579 | *const_val = *other_val; | 6588 | { |
| 6589 | copy_const_val(const_val, other_val, other_val->special == ConstValSpecialStatic); | ||
| 6590 | const_val->type = new_type; | ||
| 6591 | break; | ||
| 6592 | } | ||
| 6593 | case CastOpNumLitToConcrete: | ||
| 6594 | const_val->data.x_bignum = other_val->data.x_bignum; | ||
| 6580 | const_val->type = new_type; | 6595 | const_val->type = new_type; |
| 6581 | break; | 6596 | break; |
| 6582 | case CastOpResizeSlice: | 6597 | case CastOpResizeSlice: |
| ... | @@ -7188,7 +7203,7 @@ static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction | ... | @@ -7188,7 +7203,7 @@ static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction |
| 7188 | } | 7203 | } |
| 7189 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, | 7204 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, |
| 7190 | source_instr->source_node, wanted_type); | 7205 | source_instr->source_node, wanted_type); |
| 7191 | result->value = *val; | 7206 | result->value.data.x_bignum = val->data.x_bignum; |
| 7192 | result->value.type = wanted_type; | 7207 | result->value.type = wanted_type; |
| 7193 | return result; | 7208 | return result; |
| 7194 | } | 7209 | } |
| ... | @@ -7613,7 +7628,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -7613,7 +7628,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 7613 | (actual_type->id == TypeTableEntryIdNumLitInt && | 7628 | (actual_type->id == TypeTableEntryIdNumLitInt && |
| 7614 | wanted_type->id == TypeTableEntryIdInt)) | 7629 | wanted_type->id == TypeTableEntryIdInt)) |
| 7615 | { | 7630 | { |
| 7616 | op = CastOpNoop; | 7631 | op = CastOpNumLitToConcrete; |
| 7617 | } else if (wanted_type->id == TypeTableEntryIdInt) { | 7632 | } else if (wanted_type->id == TypeTableEntryIdInt) { |
| 7618 | op = CastOpFloatToInt; | 7633 | op = CastOpFloatToInt; |
| 7619 | } else if (wanted_type->id == TypeTableEntryIdFloat) { | 7634 | } else if (wanted_type->id == TypeTableEntryIdFloat) { |
| ... | @@ -7741,7 +7756,7 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc | ... | @@ -7741,7 +7756,7 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc |
| 7741 | if (pointee->special != ConstValSpecialRuntime) { | 7756 | if (pointee->special != ConstValSpecialRuntime) { |
| 7742 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope, | 7757 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope, |
| 7743 | source_instruction->source_node, child_type); | 7758 | source_instruction->source_node, child_type); |
| 7744 | result->value = *pointee; | 7759 | copy_const_val(&result->value, pointee, ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst); |
| 7745 | return result; | 7760 | return result; |
| 7746 | } | 7761 | } |
| 7747 | } | 7762 | } |
| ... | @@ -8584,7 +8599,7 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * | ... | @@ -8584,7 +8599,7 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * |
| 8584 | 8599 | ||
| 8585 | result_type = get_pointer_to_type(ira->codegen, child_type, true); | 8600 | result_type = get_pointer_to_type(ira->codegen, child_type, true); |
| 8586 | 8601 | ||
| 8587 | out_array_val = allocate<ConstExprValue>(1); | 8602 | out_array_val = create_const_vals(1); |
| 8588 | out_array_val->special = ConstValSpecialStatic; | 8603 | out_array_val->special = ConstValSpecialStatic; |
| 8589 | out_array_val->type = get_array_type(ira->codegen, child_type, new_len); | 8604 | out_array_val->type = get_array_type(ira->codegen, child_type, new_len); |
| 8590 | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; | 8605 | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; |
| ... | @@ -8592,7 +8607,7 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * | ... | @@ -8592,7 +8607,7 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * |
| 8592 | out_val->data.x_ptr.data.base_array.array_val = out_array_val; | 8607 | out_val->data.x_ptr.data.base_array.array_val = out_array_val; |
| 8593 | out_val->data.x_ptr.data.base_array.elem_index = 0; | 8608 | out_val->data.x_ptr.data.base_array.elem_index = 0; |
| 8594 | } | 8609 | } |
| 8595 | out_array_val->data.x_array.s_none.elements = allocate<ConstExprValue>(new_len); | 8610 | out_array_val->data.x_array.s_none.elements = create_const_vals(new_len); |
| 8596 | 8611 | ||
| 8597 | expand_undef_array(ira->codegen, op1_array_val); | 8612 | expand_undef_array(ira->codegen, op1_array_val); |
| 8598 | 8613 | ||
| ... | @@ -8648,7 +8663,7 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -8648,7 +8663,7 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp |
| 8648 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); | 8663 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 8649 | 8664 | ||
| 8650 | uint64_t new_array_len = array_len.data.x_uint; | 8665 | uint64_t new_array_len = array_len.data.x_uint; |
| 8651 | out_val->data.x_array.s_none.elements = allocate<ConstExprValue>(new_array_len); | 8666 | out_val->data.x_array.s_none.elements = create_const_vals(new_array_len); |
| 8652 | 8667 | ||
| 8653 | expand_undef_array(ira->codegen, array_val); | 8668 | expand_undef_array(ira->codegen, array_val); |
| 8654 | 8669 | ||
| ... | @@ -9139,7 +9154,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal | ... | @@ -9139,7 +9154,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 9139 | GenericFnTypeId *generic_id = allocate<GenericFnTypeId>(1); | 9154 | GenericFnTypeId *generic_id = allocate<GenericFnTypeId>(1); |
| 9140 | generic_id->fn_entry = fn_entry; | 9155 | generic_id->fn_entry = fn_entry; |
| 9141 | generic_id->param_count = 0; | 9156 | generic_id->param_count = 0; |
| 9142 | generic_id->params = allocate<ConstExprValue>(new_fn_arg_count); | 9157 | generic_id->params = create_const_vals(new_fn_arg_count); |
| 9143 | size_t next_proto_i = 0; | 9158 | size_t next_proto_i = 0; |
| 9144 | 9159 | ||
| 9145 | if (first_arg_ptr) { | 9160 | if (first_arg_ptr) { |
| ... | @@ -9451,7 +9466,7 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp | ... | @@ -9451,7 +9466,7 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp |
| 9451 | ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &value->value); | 9466 | ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &value->value); |
| 9452 | if (pointee->type == child_type) { | 9467 | if (pointee->type == child_type) { |
| 9453 | ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base); | 9468 | ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base); |
| 9454 | *out_val = *pointee; | 9469 | copy_const_val(out_val, pointee, value->value.data.x_ptr.mut == ConstPtrMutComptimeConst); |
| 9455 | return child_type; | 9470 | return child_type; |
| 9456 | } | 9471 | } |
| 9457 | } | 9472 | } |
| ... | @@ -10118,7 +10133,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source | ... | @@ -10118,7 +10133,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source |
| 10118 | 10133 | ||
| 10119 | // TODO instead of allocating this every time, put it in the tld value and we can reference | 10134 | // TODO instead of allocating this every time, put it in the tld value and we can reference |
| 10120 | // the same one every time | 10135 | // the same one every time |
| 10121 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | 10136 | ConstExprValue *const_val = create_const_vals(1); |
| 10122 | const_val->special = ConstValSpecialStatic; | 10137 | const_val->special = ConstValSpecialStatic; |
| 10123 | const_val->type = fn_entry->type_entry; | 10138 | const_val->type = fn_entry->type_entry; |
| 10124 | const_val->data.x_fn.fn_entry = fn_entry; | 10139 | const_val->data.x_fn.fn_entry = fn_entry; |
| ... | @@ -10162,7 +10177,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru | ... | @@ -10162,7 +10177,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 10162 | } | 10177 | } |
| 10163 | } else if (container_type->id == TypeTableEntryIdArray) { | 10178 | } else if (container_type->id == TypeTableEntryIdArray) { |
| 10164 | if (buf_eql_str(field_name, "len")) { | 10179 | if (buf_eql_str(field_name, "len")) { |
| 10165 | ConstExprValue *len_val = allocate<ConstExprValue>(1); | 10180 | ConstExprValue *len_val = create_const_vals(1); |
| 10166 | init_const_usize(ira->codegen, len_val, container_type->data.array.len); | 10181 | init_const_usize(ira->codegen, len_val, container_type->data.array.len); |
| 10167 | 10182 | ||
| 10168 | TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize; | 10183 | TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize; |
| ... | @@ -10185,7 +10200,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru | ... | @@ -10185,7 +10200,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 10185 | ConstExprValue *child_val = const_ptr_pointee(ira->codegen, container_ptr_val); | 10200 | ConstExprValue *child_val = const_ptr_pointee(ira->codegen, container_ptr_val); |
| 10186 | 10201 | ||
| 10187 | if (buf_eql_str(field_name, "len")) { | 10202 | if (buf_eql_str(field_name, "len")) { |
| 10188 | ConstExprValue *len_val = allocate<ConstExprValue>(1); | 10203 | ConstExprValue *len_val = create_const_vals(1); |
| 10189 | size_t len = child_val->data.x_arg_tuple.end_index - child_val->data.x_arg_tuple.start_index; | 10204 | size_t len = child_val->data.x_arg_tuple.end_index - child_val->data.x_arg_tuple.start_index; |
| 10190 | init_const_usize(ira->codegen, len_val, len); | 10205 | init_const_usize(ira->codegen, len_val, len); |
| 10191 | 10206 | ||
| ... | @@ -10258,7 +10273,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru | ... | @@ -10258,7 +10273,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 10258 | } else if (child_type->id == TypeTableEntryIdPureError) { | 10273 | } else if (child_type->id == TypeTableEntryIdPureError) { |
| 10259 | auto err_table_entry = ira->codegen->error_table.maybe_get(field_name); | 10274 | auto err_table_entry = ira->codegen->error_table.maybe_get(field_name); |
| 10260 | if (err_table_entry) { | 10275 | if (err_table_entry) { |
| 10261 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | 10276 | ConstExprValue *const_val = create_const_vals(1); |
| 10262 | const_val->special = ConstValSpecialStatic; | 10277 | const_val->special = ConstValSpecialStatic; |
| 10263 | const_val->type = child_type; | 10278 | const_val->type = child_type; |
| 10264 | const_val->data.x_pure_err = err_table_entry->value; | 10279 | const_val->data.x_pure_err = err_table_entry->value; |
| ... | @@ -11346,7 +11361,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira, | ... | @@ -11346,7 +11361,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| 11346 | case TypeTableEntryIdPureError: | 11361 | case TypeTableEntryIdPureError: |
| 11347 | if (pointee_val) { | 11362 | if (pointee_val) { |
| 11348 | ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base); | 11363 | ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base); |
| 11349 | *out_val = *pointee_val; | 11364 | copy_const_val(out_val, pointee_val, true); |
| 11350 | out_val->type = target_type; | 11365 | out_val->type = target_type; |
| 11351 | return target_type; | 11366 | return target_type; |
| 11352 | } | 11367 | } |
| ... | @@ -11583,7 +11598,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru | ... | @@ -11583,7 +11598,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru |
| 11583 | ConstExprValue const_val = {}; | 11598 | ConstExprValue const_val = {}; |
| 11584 | const_val.special = ConstValSpecialStatic; | 11599 | const_val.special = ConstValSpecialStatic; |
| 11585 | const_val.type = container_type; | 11600 | const_val.type = container_type; |
| 11586 | const_val.data.x_struct.fields = allocate<ConstExprValue>(actual_field_count); | 11601 | const_val.data.x_struct.fields = create_const_vals(actual_field_count); |
| 11587 | for (size_t i = 0; i < instr_field_count; i += 1) { | 11602 | for (size_t i = 0; i < instr_field_count; i += 1) { |
| 11588 | IrInstructionContainerInitFieldsField *field = &fields[i]; | 11603 | IrInstructionContainerInitFieldsField *field = &fields[i]; |
| 11589 | 11604 | ||
| ... | @@ -11624,7 +11639,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru | ... | @@ -11624,7 +11639,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru |
| 11624 | if (!field_val) | 11639 | if (!field_val) |
| 11625 | return ira->codegen->builtin_types.entry_invalid; | 11640 | return ira->codegen->builtin_types.entry_invalid; |
| 11626 | 11641 | ||
| 11627 | const_val.data.x_struct.fields[field_index] = *field_val; | 11642 | copy_const_val(&const_val.data.x_struct.fields[field_index], field_val, true); |
| 11628 | } else { | 11643 | } else { |
| 11629 | first_non_const_instruction = casted_field_value; | 11644 | first_non_const_instruction = casted_field_value; |
| 11630 | const_val.special = ConstValSpecialRuntime; | 11645 | const_val.special = ConstValSpecialRuntime; |
| ... | @@ -11698,7 +11713,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira | ... | @@ -11698,7 +11713,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira |
| 11698 | ConstExprValue const_val = {}; | 11713 | ConstExprValue const_val = {}; |
| 11699 | const_val.special = ConstValSpecialStatic; | 11714 | const_val.special = ConstValSpecialStatic; |
| 11700 | const_val.type = fixed_size_array_type; | 11715 | const_val.type = fixed_size_array_type; |
| 11701 | const_val.data.x_array.s_none.elements = allocate<ConstExprValue>(elem_count); | 11716 | const_val.data.x_array.s_none.elements = create_const_vals(elem_count); |
| 11702 | 11717 | ||
| 11703 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); | 11718 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); |
| 11704 | 11719 | ||
| ... | @@ -11723,7 +11738,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira | ... | @@ -11723,7 +11738,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira |
| 11723 | if (!elem_val) | 11738 | if (!elem_val) |
| 11724 | return ira->codegen->builtin_types.entry_invalid; | 11739 | return ira->codegen->builtin_types.entry_invalid; |
| 11725 | 11740 | ||
| 11726 | const_val.data.x_array.s_none.elements[i] = *elem_val; | 11741 | copy_const_val(&const_val.data.x_array.s_none.elements[i], elem_val, true); |
| 11727 | } else { | 11742 | } else { |
| 11728 | first_non_const_instruction = casted_arg; | 11743 | first_non_const_instruction = casted_arg; |
| 11729 | const_val.special = ConstValSpecialRuntime; | 11744 | const_val.special = ConstValSpecialRuntime; |
| ... | @@ -11950,7 +11965,7 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc | ... | @@ -11950,7 +11965,7 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc |
| 11950 | err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true); | 11965 | err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true); |
| 11951 | } | 11966 | } |
| 11952 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); | 11967 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 11953 | *out_val = *err->cached_error_name_val; | 11968 | copy_const_val(out_val, err->cached_error_name_val, true); |
| 11954 | return str_type; | 11969 | return str_type; |
| 11955 | } | 11970 | } |
| 11956 | 11971 | ||
| ... | @@ -12133,7 +12148,7 @@ static TypeTableEntry *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstru | ... | @@ -12133,7 +12148,7 @@ static TypeTableEntry *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstru |
| 12133 | type_entry->cached_const_name_val = create_const_str_lit(ira->codegen, &type_entry->name); | 12148 | type_entry->cached_const_name_val = create_const_str_lit(ira->codegen, &type_entry->name); |
| 12134 | } | 12149 | } |
| 12135 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); | 12150 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 12136 | *out_val = *type_entry->cached_const_name_val; | 12151 | copy_const_val(out_val, type_entry->cached_const_name_val, true); |
| 12137 | return out_val->type; | 12152 | return out_val->type; |
| 12138 | } | 12153 | } |
| 12139 | 12154 | ||
| ... | @@ -12809,7 +12824,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio | ... | @@ -12809,7 +12824,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio |
| 12809 | } | 12824 | } |
| 12810 | 12825 | ||
| 12811 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); | 12826 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 12812 | out_val->data.x_struct.fields = allocate<ConstExprValue>(2); | 12827 | out_val->data.x_struct.fields = create_const_vals(2); |
| 12813 | 12828 | ||
| 12814 | ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index]; | 12829 | ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index]; |
| 12815 | 12830 | ||
| ... | @@ -13370,7 +13385,7 @@ static TypeTableEntry *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruc | ... | @@ -13370,7 +13385,7 @@ static TypeTableEntry *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruc |
| 13370 | return ira->codegen->builtin_types.entry_invalid; | 13385 | return ira->codegen->builtin_types.entry_invalid; |
| 13371 | 13386 | ||
| 13372 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); | 13387 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 13373 | *out_val = *val; | 13388 | copy_const_val(out_val, val, false); |
| 13374 | out_val->type = dest_type; | 13389 | out_val->type = dest_type; |
| 13375 | return dest_type; | 13390 | return dest_type; |
| 13376 | } | 13391 | } |
| ... | @@ -13696,7 +13711,7 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl | ... | @@ -13696,7 +13711,7 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl |
| 13696 | ira->new_irb.exec = new_exec; | 13711 | ira->new_irb.exec = new_exec; |
| 13697 | 13712 | ||
| 13698 | ira->exec_context.mem_slot_count = ira->old_irb.exec->mem_slot_count; | 13713 | ira->exec_context.mem_slot_count = ira->old_irb.exec->mem_slot_count; |
| 13699 | ira->exec_context.mem_slot_list = allocate<ConstExprValue>(ira->exec_context.mem_slot_count); | 13714 | ira->exec_context.mem_slot_list = create_const_vals(ira->exec_context.mem_slot_count); |
| 13700 | 13715 | ||
| 13701 | IrBasicBlock *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0); | 13716 | IrBasicBlock *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0); |
| 13702 | IrBasicBlock *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr); | 13717 | IrBasicBlock *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr); |
test/cases/eval.zig+10| ... | @@ -332,3 +332,13 @@ test "compile-time downcast when the bits fit" { | ... | @@ -332,3 +332,13 @@ test "compile-time downcast when the bits fit" { |
| 332 | assert(byte == 255); | 332 | assert(byte == 255); |
| 333 | } | 333 | } |
| 334 | } | 334 | } |
| 335 | |||
| 336 | const hi1 = "hi"; | ||
| 337 | const hi2 = hi1; | ||
| 338 | test "const global shares pointer with other same one" { | ||
| 339 | assertEqualPtrs(&hi1[0], &hi2[0]); | ||
| 340 | comptime assert(&hi1[0] == &hi2[0]); | ||
| 341 | } | ||
| 342 | fn assertEqualPtrs(ptr1: &const u8, ptr2: &const u8) { | ||
| 343 | assert(ptr1 == ptr2); | ||
| 344 | } |
test/cases/var_args.zig+14| ... | @@ -65,3 +65,17 @@ test "array of var args functions" { | ... | @@ -65,3 +65,17 @@ test "array of var args functions" { |
| 65 | assert(foos[0]()); | 65 | assert(foos[0]()); |
| 66 | assert(!foos[1]()); | 66 | assert(!foos[1]()); |
| 67 | } | 67 | } |
| 68 | |||
| 69 | |||
| 70 | test "pass array and slice of same array to var args should have same pointers" { | ||
| 71 | const array = "hi"; | ||
| 72 | const slice: []const u8 = array; | ||
| 73 | return assertSlicePtrsEql(array, slice); | ||
| 74 | } | ||
| 75 | |||
| 76 | fn assertSlicePtrsEql(args: ...) { | ||
| 77 | const s1 = ([]const u8)(args[0]); | ||
| 78 | const s2 = args[1]; | ||
| 79 | assert(s1.ptr == s2.ptr); | ||
| 80 | } | ||
| 81 |
test/tests.zig+2-4| ... | @@ -591,8 +591,7 @@ pub const CompileErrorContext = struct { | ... | @@ -591,8 +591,7 @@ pub const CompileErrorContext = struct { |
| 591 | tc.addSourceFile(".tmp_source.zig", source); | 591 | tc.addSourceFile(".tmp_source.zig", source); |
| 592 | comptime var arg_i = 0; | 592 | comptime var arg_i = 0; |
| 593 | inline while (arg_i < expected_lines.len) : (arg_i += 1) { | 593 | inline while (arg_i < expected_lines.len) : (arg_i += 1) { |
| 594 | // TODO mem.dupe is because of issue #336 | 594 | tc.addExpectedError(expected_lines[arg_i]); |
| 595 | tc.addExpectedError(%%mem.dupe(self.b.allocator, u8, expected_lines[arg_i])); | ||
| 596 | } | 595 | } |
| 597 | return tc; | 596 | return tc; |
| 598 | } | 597 | } |
| ... | @@ -854,8 +853,7 @@ pub const ParseHContext = struct { | ... | @@ -854,8 +853,7 @@ pub const ParseHContext = struct { |
| 854 | tc.addSourceFile("source.h", source); | 853 | tc.addSourceFile("source.h", source); |
| 855 | comptime var arg_i = 0; | 854 | comptime var arg_i = 0; |
| 856 | inline while (arg_i < expected_lines.len) : (arg_i += 1) { | 855 | inline while (arg_i < expected_lines.len) : (arg_i += 1) { |
| 857 | // TODO mem.dupe is because of issue #336 | 856 | tc.addExpectedError(expected_lines[arg_i]); |
| 858 | tc.addExpectedError(%%mem.dupe(self.b.allocator, u8, expected_lines[arg_i])); | ||
| 859 | } | 857 | } |
| 860 | return tc; | 858 | return tc; |
| 861 | } | 859 | } |