| ... | @@ -961,10 +961,12 @@ static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, Zi | ... | @@ -961,10 +961,12 @@ static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, Zi |
| 961 | Error err; | 961 | Error err; |
| 962 | if (type_val->special != ConstValSpecialLazy) { | 962 | if (type_val->special != ConstValSpecialLazy) { |
| 963 | assert(type_val->special == ConstValSpecialStatic); | 963 | assert(type_val->special == ConstValSpecialStatic); |
| 964 | if (type_val->data.x_type->id == ZigTypeIdStruct && | 964 | if ((type_val->data.x_type->id == ZigTypeIdStruct && |
| 965 | type_val->data.x_type->data.structure.resolve_loop_flag_zero_bits) | 965 | type_val->data.x_type->data.structure.resolve_loop_flag_zero_bits) || |
| | 966 | (type_val->data.x_type->id == ZigTypeIdUnion && |
| | 967 | type_val->data.x_type->data.unionation.resolve_loop_flag_zero_bits)) |
| 966 | { | 968 | { |
| 967 | // Does a struct which contains a pointer field to itself have bits? Yes. | 969 | // Does a struct/union which contains a pointer field to itself have bits? Yes. |
| 968 | *is_zero_bits = false; | 970 | *is_zero_bits = false; |
| 969 | return ErrorNone; | 971 | return ErrorNone; |
| 970 | } | 972 | } |
| ... | @@ -1079,7 +1081,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue | ... | @@ -1079,7 +1081,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue |
| 1079 | zig_unreachable(); | 1081 | zig_unreachable(); |
| 1080 | } | 1082 | } |
| 1081 | | 1083 | |
| 1082 | static Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, size_t *abi_align) { | 1084 | static Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t *abi_align) { |
| 1083 | Error err; | 1085 | Error err; |
| 1084 | if (type_val->special != ConstValSpecialLazy) { | 1086 | if (type_val->special != ConstValSpecialLazy) { |
| 1085 | assert(type_val->special == ConstValSpecialStatic); | 1087 | assert(type_val->special == ConstValSpecialStatic); |
| ... | @@ -1917,7 +1919,7 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { | ... | @@ -1917,7 +1919,7 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { |
| 1917 | | 1919 | |
| 1918 | AstNode *decl_node = union_type->data.structure.decl_node; | 1920 | AstNode *decl_node = union_type->data.structure.decl_node; |
| 1919 | | 1921 | |
| 1920 | if (union_type->data.unionation.resolve_loop_flag) { | 1922 | if (union_type->data.unionation.resolve_loop_flag_other) { |
| 1921 | if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) { | 1923 | if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) { |
| 1922 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | 1924 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| 1923 | g->trace_err = add_node_error(g, decl_node, | 1925 | g->trace_err = add_node_error(g, decl_node, |
| ... | @@ -1927,9 +1929,9 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { | ... | @@ -1927,9 +1929,9 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { |
| 1927 | } | 1929 | } |
| 1928 | | 1930 | |
| 1929 | // set temporary flag | 1931 | // set temporary flag |
| 1930 | union_type->data.unionation.resolve_loop_flag = true; | 1932 | union_type->data.unionation.resolve_loop_flag_other = true; |
| 1931 | | 1933 | |
| 1932 | ZigType *most_aligned_union_member = nullptr; | 1934 | TypeUnionField *most_aligned_union_member = nullptr; |
| 1933 | uint32_t field_count = union_type->data.unionation.src_field_count; | 1935 | uint32_t field_count = union_type->data.unionation.src_field_count; |
| 1934 | bool packed = union_type->data.unionation.layout == ContainerLayoutPacked; | 1936 | bool packed = union_type->data.unionation.layout == ContainerLayoutPacked; |
| 1935 | | 1937 | |
| ... | @@ -1938,33 +1940,32 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { | ... | @@ -1938,33 +1940,32 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { |
| 1938 | if (field->gen_index == UINT32_MAX) | 1940 | if (field->gen_index == UINT32_MAX) |
| 1939 | continue; | 1941 | continue; |
| 1940 | | 1942 | |
| 1941 | src_assert(field->type_entry != nullptr, decl_node); | 1943 | AstNode *align_expr = field->decl_node->data.struct_field.align_expr; |
| 1942 | | 1944 | if (align_expr != nullptr) { |
| 1943 | size_t this_field_align; | 1945 | if (!analyze_const_align(g, &union_type->data.unionation.decls_scope->base, align_expr, |
| 1944 | if (packed) { | 1946 | &field->align)) |
| 1945 | // TODO: https://github.com/ziglang/zig/issues/1512 | 1947 | { |
| 1946 | this_field_align = 1; | 1948 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| | 1949 | return err; |
| | 1950 | } |
| | 1951 | } else if (packed) { |
| | 1952 | field->align = 1; |
| 1947 | } else { | 1953 | } else { |
| 1948 | if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) { | 1954 | if ((err = type_val_resolve_abi_align(g, field->type_val, &field->align))) { |
| 1949 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | 1955 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| 1950 | return ErrorSemanticAnalyzeFail; | 1956 | return err; |
| 1951 | } | 1957 | } |
| 1952 | | | |
| 1953 | if (union_type->data.unionation.resolve_status == ResolveStatusInvalid) | 1958 | if (union_type->data.unionation.resolve_status == ResolveStatusInvalid) |
| 1954 | return ErrorSemanticAnalyzeFail; | 1959 | return ErrorSemanticAnalyzeFail; |
| 1955 | | | |
| 1956 | this_field_align = field->type_entry->abi_align; | | |
| 1957 | } | 1960 | } |
| 1958 | | 1961 | |
| 1959 | if (most_aligned_union_member == nullptr || | 1962 | if (most_aligned_union_member == nullptr || field->align > most_aligned_union_member->align) { |
| 1960 | this_field_align > most_aligned_union_member->abi_align) | 1963 | most_aligned_union_member = field; |
| 1961 | { | | |
| 1962 | most_aligned_union_member = field->type_entry; | | |
| 1963 | } | 1964 | } |
| 1964 | } | 1965 | } |
| 1965 | | 1966 | |
| 1966 | // unset temporary flag | 1967 | // unset temporary flag |
| 1967 | union_type->data.unionation.resolve_loop_flag = false; | 1968 | union_type->data.unionation.resolve_loop_flag_other = false; |
| 1968 | union_type->data.unionation.resolve_status = ResolveStatusAlignmentKnown; | 1969 | union_type->data.unionation.resolve_status = ResolveStatusAlignmentKnown; |
| 1969 | union_type->data.unionation.most_aligned_union_member = most_aligned_union_member; | 1970 | union_type->data.unionation.most_aligned_union_member = most_aligned_union_member; |
| 1970 | | 1971 | |
| ... | @@ -1978,18 +1979,18 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { | ... | @@ -1978,18 +1979,18 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { |
| 1978 | union_type->abi_align = tag_type->abi_align; | 1979 | union_type->abi_align = tag_type->abi_align; |
| 1979 | union_type->data.unionation.gen_tag_index = SIZE_MAX; | 1980 | union_type->data.unionation.gen_tag_index = SIZE_MAX; |
| 1980 | union_type->data.unionation.gen_union_index = SIZE_MAX; | 1981 | union_type->data.unionation.gen_union_index = SIZE_MAX; |
| 1981 | } else if (tag_type->abi_align > most_aligned_union_member->abi_align) { | 1982 | } else if (tag_type->abi_align > most_aligned_union_member->align) { |
| 1982 | union_type->abi_align = tag_type->abi_align; | 1983 | union_type->abi_align = tag_type->abi_align; |
| 1983 | union_type->data.unionation.gen_tag_index = 0; | 1984 | union_type->data.unionation.gen_tag_index = 0; |
| 1984 | union_type->data.unionation.gen_union_index = 1; | 1985 | union_type->data.unionation.gen_union_index = 1; |
| 1985 | } else { | 1986 | } else { |
| 1986 | union_type->abi_align = most_aligned_union_member->abi_align; | 1987 | union_type->abi_align = most_aligned_union_member->align; |
| 1987 | union_type->data.unionation.gen_union_index = 0; | 1988 | union_type->data.unionation.gen_union_index = 0; |
| 1988 | union_type->data.unionation.gen_tag_index = 1; | 1989 | union_type->data.unionation.gen_tag_index = 1; |
| 1989 | } | 1990 | } |
| 1990 | } else { | 1991 | } else { |
| 1991 | assert(most_aligned_union_member != nullptr); | 1992 | assert(most_aligned_union_member != nullptr); |
| 1992 | union_type->abi_align = most_aligned_union_member->abi_align; | 1993 | union_type->abi_align = most_aligned_union_member->align; |
| 1993 | union_type->data.unionation.gen_union_index = SIZE_MAX; | 1994 | union_type->data.unionation.gen_union_index = SIZE_MAX; |
| 1994 | union_type->data.unionation.gen_tag_index = SIZE_MAX; | 1995 | union_type->data.unionation.gen_tag_index = SIZE_MAX; |
| 1995 | } | 1996 | } |
| ... | @@ -2016,14 +2017,14 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { | ... | @@ -2016,14 +2017,14 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { |
| 2016 | assert(decl_node->type == NodeTypeContainerDecl); | 2017 | assert(decl_node->type == NodeTypeContainerDecl); |
| 2017 | | 2018 | |
| 2018 | uint32_t field_count = union_type->data.unionation.src_field_count; | 2019 | uint32_t field_count = union_type->data.unionation.src_field_count; |
| 2019 | ZigType *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member; | 2020 | TypeUnionField *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member; |
| 2020 | | 2021 | |
| 2021 | assert(union_type->data.unionation.fields); | 2022 | assert(union_type->data.unionation.fields); |
| 2022 | | 2023 | |
| 2023 | size_t union_abi_size = 0; | 2024 | size_t union_abi_size = 0; |
| 2024 | size_t union_size_in_bits = 0; | 2025 | size_t union_size_in_bits = 0; |
| 2025 | | 2026 | |
| 2026 | if (union_type->data.unionation.resolve_loop_flag) { | 2027 | if (union_type->data.unionation.resolve_loop_flag_other) { |
| 2027 | if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) { | 2028 | if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) { |
| 2028 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | 2029 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| 2029 | g->trace_err = add_node_error(g, decl_node, | 2030 | g->trace_err = add_node_error(g, decl_node, |
| ... | @@ -2033,11 +2034,18 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { | ... | @@ -2033,11 +2034,18 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { |
| 2033 | } | 2034 | } |
| 2034 | | 2035 | |
| 2035 | // set temporary flag | 2036 | // set temporary flag |
| 2036 | union_type->data.unionation.resolve_loop_flag = true; | 2037 | union_type->data.unionation.resolve_loop_flag_other = true; |
| 2037 | | 2038 | |
| 2038 | for (uint32_t i = 0; i < field_count; i += 1) { | 2039 | for (uint32_t i = 0; i < field_count; i += 1) { |
| | 2040 | AstNode *field_source_node = decl_node->data.container_decl.fields.at(i); |
| 2039 | TypeUnionField *union_field = &union_type->data.unionation.fields[i]; | 2041 | TypeUnionField *union_field = &union_type->data.unionation.fields[i]; |
| 2040 | ZigType *field_type = union_field->type_entry; | 2042 | |
| | 2043 | if ((err = ir_resolve_lazy(g, field_source_node, union_field->type_val))) { |
| | 2044 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| | 2045 | return err; |
| | 2046 | } |
| | 2047 | ZigType *field_type = union_field->type_val->data.x_type; |
| | 2048 | union_field->type_entry = field_type; |
| 2041 | | 2049 | |
| 2042 | if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) { | 2050 | if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) { |
| 2043 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | 2051 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| ... | @@ -2057,11 +2065,11 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { | ... | @@ -2057,11 +2065,11 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { |
| 2057 | // The union itself for now has to be treated as being independently aligned. | 2065 | // The union itself for now has to be treated as being independently aligned. |
| 2058 | // See https://github.com/ziglang/zig/issues/2166. | 2066 | // See https://github.com/ziglang/zig/issues/2166. |
| 2059 | if (most_aligned_union_member != nullptr) { | 2067 | if (most_aligned_union_member != nullptr) { |
| 2060 | union_abi_size = align_forward(union_abi_size, most_aligned_union_member->abi_align); | 2068 | union_abi_size = align_forward(union_abi_size, most_aligned_union_member->align); |
| 2061 | } | 2069 | } |
| 2062 | | 2070 | |
| 2063 | // unset temporary flag | 2071 | // unset temporary flag |
| 2064 | union_type->data.unionation.resolve_loop_flag = false; | 2072 | union_type->data.unionation.resolve_loop_flag_other = false; |
| 2065 | union_type->data.unionation.resolve_status = ResolveStatusSizeKnown; | 2073 | union_type->data.unionation.resolve_status = ResolveStatusSizeKnown; |
| 2066 | union_type->data.unionation.union_abi_size = union_abi_size; | 2074 | union_type->data.unionation.union_abi_size = union_abi_size; |
| 2067 | | 2075 | |
| ... | @@ -2080,7 +2088,7 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { | ... | @@ -2080,7 +2088,7 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { |
| 2080 | field_sizes[union_type->data.unionation.gen_tag_index] = tag_type->abi_size; | 2088 | field_sizes[union_type->data.unionation.gen_tag_index] = tag_type->abi_size; |
| 2081 | field_aligns[union_type->data.unionation.gen_tag_index] = tag_type->abi_align; | 2089 | field_aligns[union_type->data.unionation.gen_tag_index] = tag_type->abi_align; |
| 2082 | field_sizes[union_type->data.unionation.gen_union_index] = union_abi_size; | 2090 | field_sizes[union_type->data.unionation.gen_union_index] = union_abi_size; |
| 2083 | field_aligns[union_type->data.unionation.gen_union_index] = most_aligned_union_member->abi_align; | 2091 | field_aligns[union_type->data.unionation.gen_union_index] = most_aligned_union_member->align; |
| 2084 | size_t field2_offset = next_field_offset(0, union_type->abi_align, field_sizes[0], field_aligns[1]); | 2092 | size_t field2_offset = next_field_offset(0, union_type->abi_align, field_sizes[0], field_aligns[1]); |
| 2085 | union_type->abi_size = next_field_offset(field2_offset, union_type->abi_align, field_sizes[1], union_type->abi_align); | 2093 | union_type->abi_size = next_field_offset(field2_offset, union_type->abi_align, field_sizes[1], union_type->abi_align); |
| 2086 | union_type->size_in_bits = union_type->abi_size * 8; | 2094 | union_type->size_in_bits = union_type->abi_size * 8; |
| ... | @@ -2449,12 +2457,12 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { | ... | @@ -2449,12 +2457,12 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { |
| 2449 | } else if (packed) { | 2457 | } else if (packed) { |
| 2450 | field->align = 1; | 2458 | field->align = 1; |
| 2451 | } else { | 2459 | } else { |
| 2452 | size_t result_abi_align; | 2460 | if ((err = type_val_resolve_abi_align(g, field->type_val, &field->align))) { |
| 2453 | if ((err = type_val_resolve_abi_align(g, field->type_val, &result_abi_align))) { | | |
| 2454 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | 2461 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2455 | return err; | 2462 | return err; |
| 2456 | } | 2463 | } |
| 2457 | field->align = result_abi_align; | 2464 | if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) |
| | 2465 | return ErrorSemanticAnalyzeFail; |
| 2458 | } | 2466 | } |
| 2459 | | 2467 | |
| 2460 | if (field->align > struct_type->abi_align) { | 2468 | if (field->align > struct_type->abi_align) { |
| ... | @@ -2486,7 +2494,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { | ... | @@ -2486,7 +2494,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { |
| 2486 | AstNode *decl_node = union_type->data.unionation.decl_node; | 2494 | AstNode *decl_node = union_type->data.unionation.decl_node; |
| 2487 | assert(decl_node->type == NodeTypeContainerDecl); | 2495 | assert(decl_node->type == NodeTypeContainerDecl); |
| 2488 | | 2496 | |
| 2489 | if (union_type->data.unionation.resolve_loop_flag) { | 2497 | if (union_type->data.unionation.resolve_loop_flag_zero_bits) { |
| 2490 | if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) { | 2498 | if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) { |
| 2491 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | 2499 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| 2492 | g->trace_err = add_node_error(g, decl_node, | 2500 | g->trace_err = add_node_error(g, decl_node, |
| ... | @@ -2496,7 +2504,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { | ... | @@ -2496,7 +2504,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { |
| 2496 | return ErrorSemanticAnalyzeFail; | 2504 | return ErrorSemanticAnalyzeFail; |
| 2497 | } | 2505 | } |
| 2498 | | 2506 | |
| 2499 | union_type->data.unionation.resolve_loop_flag = true; | 2507 | union_type->data.unionation.resolve_loop_flag_zero_bits = true; |
| 2500 | | 2508 | |
| 2501 | assert(union_type->data.unionation.fields == nullptr); | 2509 | assert(union_type->data.unionation.fields == nullptr); |
| 2502 | uint32_t field_count = (uint32_t)decl_node->data.container_decl.fields.length; | 2510 | uint32_t field_count = (uint32_t)decl_node->data.container_decl.fields.length; |
| ... | @@ -2605,49 +2613,68 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { | ... | @@ -2605,49 +2613,68 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { |
| 2605 | return ErrorSemanticAnalyzeFail; | 2613 | return ErrorSemanticAnalyzeFail; |
| 2606 | } | 2614 | } |
| 2607 | | 2615 | |
| 2608 | ZigType *field_type; | 2616 | bool field_is_zero_bits; |
| 2609 | if (field_node->data.struct_field.type == nullptr) { | 2617 | if (field_node->data.struct_field.type == nullptr) { |
| 2610 | if (decl_node->data.container_decl.auto_enum || decl_node->data.container_decl.init_arg_expr != nullptr) { | 2618 | if (decl_node->data.container_decl.auto_enum || |
| 2611 | field_type = g->builtin_types.entry_void; | 2619 | decl_node->data.container_decl.init_arg_expr != nullptr) |
| | 2620 | { |
| | 2621 | union_field->type_entry = g->builtin_types.entry_void; |
| | 2622 | field_is_zero_bits = false; |
| 2612 | } else { | 2623 | } else { |
| 2613 | add_node_error(g, field_node, buf_sprintf("union field missing type")); | 2624 | add_node_error(g, field_node, buf_sprintf("union field missing type")); |
| 2614 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | 2625 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| 2615 | return ErrorSemanticAnalyzeFail; | 2626 | return ErrorSemanticAnalyzeFail; |
| 2616 | } | 2627 | } |
| 2617 | } else { | 2628 | } else { |
| 2618 | field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type); | 2629 | ConstExprValue *field_type_val = analyze_const_value_allow_lazy(g, scope, |
| 2619 | if ((err = type_resolve(g, field_type, ResolveStatusAlignmentKnown))) { | 2630 | field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, true); |
| | 2631 | if (type_is_invalid(field_type_val->type)) { |
| 2620 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | 2632 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| 2621 | return ErrorSemanticAnalyzeFail; | 2633 | return ErrorSemanticAnalyzeFail; |
| 2622 | } | 2634 | } |
| | 2635 | assert(field_type_val->special != ConstValSpecialRuntime); |
| | 2636 | union_field->type_val = field_type_val; |
| 2623 | if (union_type->data.unionation.resolve_status == ResolveStatusInvalid) | 2637 | if (union_type->data.unionation.resolve_status == ResolveStatusInvalid) |
| 2624 | return ErrorSemanticAnalyzeFail; | 2638 | return ErrorSemanticAnalyzeFail; |
| 2625 | } | | |
| 2626 | union_field->type_entry = field_type; | | |
| 2627 | | 2639 | |
| 2628 | if (field_type->id == ZigTypeIdOpaque) { | 2640 | bool field_is_opaque_type; |
| 2629 | add_node_error(g, field_node->data.struct_field.type, | 2641 | if ((err = type_val_resolve_is_opaque_type(g, field_type_val, &field_is_opaque_type))) { |
| 2630 | buf_sprintf("opaque types have unknown size and therefore cannot be directly embedded in unions")); | 2642 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| 2631 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | 2643 | return ErrorSemanticAnalyzeFail; |
| 2632 | return ErrorSemanticAnalyzeFail; | 2644 | } |
| 2633 | } | 2645 | if (field_is_opaque_type) { |
| | 2646 | add_node_error(g, field_node->data.struct_field.type, |
| | 2647 | buf_create_from_str( |
| | 2648 | "opaque types have unknown size and therefore cannot be directly embedded in unions")); |
| | 2649 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| | 2650 | return ErrorSemanticAnalyzeFail; |
| | 2651 | } |
| 2634 | | 2652 | |
| 2635 | switch (type_requires_comptime(g, field_type)) { | 2653 | switch (type_val_resolve_requires_comptime(g, field_type_val)) { |
| 2636 | case ReqCompTimeInvalid: | 2654 | case ReqCompTimeInvalid: |
| | 2655 | if (g->trace_err != nullptr) { |
| | 2656 | g->trace_err = add_error_note(g, g->trace_err, field_node, |
| | 2657 | buf_create_from_str("while checking this field")); |
| | 2658 | } |
| | 2659 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| | 2660 | return ErrorSemanticAnalyzeFail; |
| | 2661 | case ReqCompTimeYes: |
| | 2662 | union_type->data.unionation.requires_comptime = true; |
| | 2663 | break; |
| | 2664 | case ReqCompTimeNo: |
| | 2665 | break; |
| | 2666 | } |
| | 2667 | |
| | 2668 | if ((err = type_val_resolve_zero_bits(g, field_type_val, union_type, nullptr, &field_is_zero_bits))) { |
| 2637 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | 2669 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| 2638 | return ErrorSemanticAnalyzeFail; | 2670 | return ErrorSemanticAnalyzeFail; |
| 2639 | case ReqCompTimeYes: | 2671 | } |
| 2640 | union_type->data.unionation.requires_comptime = true; | | |
| 2641 | break; | | |
| 2642 | case ReqCompTimeNo: | | |
| 2643 | break; | | |
| 2644 | } | 2672 | } |
| 2645 | | 2673 | |
| 2646 | if (field_node->data.struct_field.value != nullptr && !decl_node->data.container_decl.auto_enum) { | 2674 | if (field_node->data.struct_field.value != nullptr && !decl_node->data.container_decl.auto_enum) { |
| 2647 | ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.value, | 2675 | ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.value, |
| 2648 | buf_sprintf("non-enum union field assignment")); | 2676 | buf_create_from_str("untagged union field assignment")); |
| 2649 | add_error_note(g, msg, decl_node, | 2677 | add_error_note(g, msg, decl_node, buf_create_from_str("consider 'union(enum)' here")); |
| 2650 | buf_sprintf("consider 'union(enum)' here")); | | |
| 2651 | } | 2678 | } |
| 2652 | | 2679 | |
| 2653 | if (create_enum_type) { | 2680 | if (create_enum_type) { |
| ... | @@ -2706,7 +2733,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { | ... | @@ -2706,7 +2733,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { |
| 2706 | } | 2733 | } |
| 2707 | assert(union_field->enum_field != nullptr); | 2734 | assert(union_field->enum_field != nullptr); |
| 2708 | | 2735 | |
| 2709 | if (!type_has_bits(field_type)) | 2736 | if (field_is_zero_bits) |
| 2710 | continue; | 2737 | continue; |
| 2711 | | 2738 | |
| 2712 | union_field->gen_index = gen_field_index; | 2739 | union_field->gen_index = gen_field_index; |
| ... | @@ -2783,7 +2810,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { | ... | @@ -2783,7 +2810,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { |
| 2783 | return ErrorSemanticAnalyzeFail; | 2810 | return ErrorSemanticAnalyzeFail; |
| 2784 | } | 2811 | } |
| 2785 | | 2812 | |
| 2786 | union_type->data.unionation.resolve_loop_flag = false; | 2813 | union_type->data.unionation.resolve_loop_flag_zero_bits = false; |
| 2787 | | 2814 | |
| 2788 | union_type->data.unionation.gen_field_count = gen_field_index; | 2815 | union_type->data.unionation.gen_field_count = gen_field_index; |
| 2789 | bool zero_bits = gen_field_index == 0 && (field_count < 2 || !src_have_tag); | 2816 | bool zero_bits = gen_field_index == 0 && (field_count < 2 || !src_have_tag); |
| ... | @@ -5002,6 +5029,10 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *ty) { | ... | @@ -5002,6 +5029,10 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *ty) { |
| 5002 | return ReqCompTimeInvalid; | 5029 | return ReqCompTimeInvalid; |
| 5003 | return ty->data.structure.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo; | 5030 | return ty->data.structure.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo; |
| 5004 | case ZigTypeIdUnion: | 5031 | case ZigTypeIdUnion: |
| | 5032 | if (ty->data.unionation.resolve_loop_flag_zero_bits) { |
| | 5033 | // Does a union which contains a pointer field to itself require comptime? No. |
| | 5034 | return ReqCompTimeNo; |
| | 5035 | } |
| 5005 | if ((err = type_resolve(g, ty, ResolveStatusZeroBitsKnown))) | 5036 | if ((err = type_resolve(g, ty, ResolveStatusZeroBitsKnown))) |
| 5006 | return ReqCompTimeInvalid; | 5037 | return ReqCompTimeInvalid; |
| 5007 | return ty->data.unionation.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo; | 5038 | return ty->data.unionation.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo; |
| ... | @@ -7308,7 +7339,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatu | ... | @@ -7308,7 +7339,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatu |
| 7308 | static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveStatus wanted_resolve_status) { | 7339 | static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveStatus wanted_resolve_status) { |
| 7309 | if (union_type->data.unionation.resolve_status >= wanted_resolve_status) return; | 7340 | if (union_type->data.unionation.resolve_status >= wanted_resolve_status) return; |
| 7310 | | 7341 | |
| 7311 | ZigType *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member; | 7342 | TypeUnionField *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member; |
| 7312 | ZigType *tag_type = union_type->data.unionation.tag_type; | 7343 | ZigType *tag_type = union_type->data.unionation.tag_type; |
| 7313 | if (most_aligned_union_member == nullptr) { | 7344 | if (most_aligned_union_member == nullptr) { |
| 7314 | union_type->llvm_type = get_llvm_type(g, tag_type); | 7345 | union_type->llvm_type = get_llvm_type(g, tag_type); |
| ... | @@ -7361,17 +7392,17 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta | ... | @@ -7361,17 +7392,17 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta |
| 7361 | if (tag_type == nullptr || !type_has_bits(tag_type)) { | 7392 | if (tag_type == nullptr || !type_has_bits(tag_type)) { |
| 7362 | assert(most_aligned_union_member != nullptr); | 7393 | assert(most_aligned_union_member != nullptr); |
| 7363 | | 7394 | |
| 7364 | size_t padding_bytes = union_type->data.unionation.union_abi_size - most_aligned_union_member->abi_size; | 7395 | size_t padding_bytes = union_type->data.unionation.union_abi_size - most_aligned_union_member->type_entry->abi_size; |
| 7365 | if (padding_bytes > 0) { | 7396 | if (padding_bytes > 0) { |
| 7366 | ZigType *u8_type = get_int_type(g, false, 8); | 7397 | ZigType *u8_type = get_int_type(g, false, 8); |
| 7367 | ZigType *padding_array = get_array_type(g, u8_type, padding_bytes); | 7398 | ZigType *padding_array = get_array_type(g, u8_type, padding_bytes); |
| 7368 | LLVMTypeRef union_element_types[] = { | 7399 | LLVMTypeRef union_element_types[] = { |
| 7369 | most_aligned_union_member->llvm_type, | 7400 | most_aligned_union_member->type_entry->llvm_type, |
| 7370 | get_llvm_type(g, padding_array), | 7401 | get_llvm_type(g, padding_array), |
| 7371 | }; | 7402 | }; |
| 7372 | LLVMStructSetBody(union_type->llvm_type, union_element_types, 2, false); | 7403 | LLVMStructSetBody(union_type->llvm_type, union_element_types, 2, false); |
| 7373 | } else { | 7404 | } else { |
| 7374 | LLVMStructSetBody(union_type->llvm_type, &most_aligned_union_member->llvm_type, 1, false); | 7405 | LLVMStructSetBody(union_type->llvm_type, &most_aligned_union_member->type_entry->llvm_type, 1, false); |
| 7375 | } | 7406 | } |
| 7376 | union_type->data.unionation.union_llvm_type = union_type->llvm_type; | 7407 | union_type->data.unionation.union_llvm_type = union_type->llvm_type; |
| 7377 | union_type->data.unionation.gen_tag_index = SIZE_MAX; | 7408 | union_type->data.unionation.gen_tag_index = SIZE_MAX; |
| ... | @@ -7382,7 +7413,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta | ... | @@ -7382,7 +7413,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta |
| 7382 | ZigLLVMFileToScope(import->data.structure.root_struct->di_file), buf_ptr(&union_type->name), | 7413 | ZigLLVMFileToScope(import->data.structure.root_struct->di_file), buf_ptr(&union_type->name), |
| 7383 | import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1), | 7414 | import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1), |
| 7384 | union_type->data.unionation.union_abi_size * 8, | 7415 | union_type->data.unionation.union_abi_size * 8, |
| 7385 | most_aligned_union_member->abi_align * 8, | 7416 | most_aligned_union_member->align * 8, |
| 7386 | ZigLLVM_DIFlags_Zero, union_inner_di_types, | 7417 | ZigLLVM_DIFlags_Zero, union_inner_di_types, |
| 7387 | gen_field_count, 0, ""); | 7418 | gen_field_count, 0, ""); |
| 7388 | | 7419 | |
| ... | @@ -7393,14 +7424,14 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta | ... | @@ -7393,14 +7424,14 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta |
| 7393 | } | 7424 | } |
| 7394 | | 7425 | |
| 7395 | LLVMTypeRef union_type_ref; | 7426 | LLVMTypeRef union_type_ref; |
| 7396 | size_t padding_bytes = union_type->data.unionation.union_abi_size - most_aligned_union_member->abi_size; | 7427 | size_t padding_bytes = union_type->data.unionation.union_abi_size - most_aligned_union_member->type_entry->abi_size; |
| 7397 | if (padding_bytes == 0) { | 7428 | if (padding_bytes == 0) { |
| 7398 | union_type_ref = get_llvm_type(g, most_aligned_union_member); | 7429 | union_type_ref = get_llvm_type(g, most_aligned_union_member->type_entry); |
| 7399 | } else { | 7430 | } else { |
| 7400 | ZigType *u8_type = get_int_type(g, false, 8); | 7431 | ZigType *u8_type = get_int_type(g, false, 8); |
| 7401 | ZigType *padding_array = get_array_type(g, u8_type, padding_bytes); | 7432 | ZigType *padding_array = get_array_type(g, u8_type, padding_bytes); |
| 7402 | LLVMTypeRef union_element_types[] = { | 7433 | LLVMTypeRef union_element_types[] = { |
| 7403 | get_llvm_type(g, most_aligned_union_member), | 7434 | get_llvm_type(g, most_aligned_union_member->type_entry), |
| 7404 | get_llvm_type(g, padding_array), | 7435 | get_llvm_type(g, padding_array), |
| 7405 | }; | 7436 | }; |
| 7406 | union_type_ref = LLVMStructType(union_element_types, 2, false); | 7437 | union_type_ref = LLVMStructType(union_element_types, 2, false); |
| ... | @@ -7416,7 +7447,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta | ... | @@ -7416,7 +7447,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta |
| 7416 | ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder, | 7447 | ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder, |
| 7417 | ZigLLVMTypeToScope(union_type->llvm_di_type), "AnonUnion", | 7448 | ZigLLVMTypeToScope(union_type->llvm_di_type), "AnonUnion", |
| 7418 | import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1), | 7449 | import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1), |
| 7419 | most_aligned_union_member->size_in_bits, 8*most_aligned_union_member->abi_align, | 7450 | most_aligned_union_member->type_entry->size_in_bits, 8*most_aligned_union_member->align, |
| 7420 | ZigLLVM_DIFlags_Zero, union_inner_di_types, gen_field_count, 0, ""); | 7451 | ZigLLVM_DIFlags_Zero, union_inner_di_types, gen_field_count, 0, ""); |
| 7421 | | 7452 | |
| 7422 | uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, union_type->llvm_type, | 7453 | uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, union_type->llvm_type, |
| ... | @@ -7427,8 +7458,8 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta | ... | @@ -7427,8 +7458,8 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta |
| 7427 | ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder, | 7458 | ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder, |
| 7428 | ZigLLVMTypeToScope(union_type->llvm_di_type), "payload", | 7459 | ZigLLVMTypeToScope(union_type->llvm_di_type), "payload", |
| 7429 | import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1), | 7460 | import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1), |
| 7430 | most_aligned_union_member->size_in_bits, | 7461 | most_aligned_union_member->type_entry->size_in_bits, |
| 7431 | 8*most_aligned_union_member->abi_align, | 7462 | 8*most_aligned_union_member->align, |
| 7432 | union_offset_in_bits, | 7463 | union_offset_in_bits, |
| 7433 | ZigLLVM_DIFlags_Zero, union_di_type); | 7464 | ZigLLVM_DIFlags_Zero, union_di_type); |
| 7434 | | 7465 | |