| author | |
| committer | |
| log | 3dc8448680cfea2b55a6064c655e400e31e5d3dd |
| tree | b8fc52931b21831c5346a956824abcf52011519f |
| parent | ee5064c053526e9e6a0a94d835cd334eea2e5823 |
| signature | Commit is signed but in an unrecognized format. |
but I think it's a bad idea, so I'm going to back out the change6 files changed, 681 insertions(+), 264 deletions(-)
src/all_types.hpp+42-2| ... | @@ -256,6 +256,7 @@ enum ConstValSpecial { | ... | @@ -256,6 +256,7 @@ enum ConstValSpecial { |
| 256 | ConstValSpecialRuntime, | 256 | ConstValSpecialRuntime, |
| 257 | ConstValSpecialStatic, | 257 | ConstValSpecialStatic, |
| 258 | ConstValSpecialUndef, | 258 | ConstValSpecialUndef, |
| 259 | ConstValSpecialLazy, | ||
| 259 | }; | 260 | }; |
| 260 | 261 | ||
| 261 | enum RuntimeHintErrorUnion { | 262 | enum RuntimeHintErrorUnion { |
| ... | @@ -291,6 +292,43 @@ struct ConstGlobalRefs { | ... | @@ -291,6 +292,43 @@ struct ConstGlobalRefs { |
| 291 | LLVMValueRef llvm_global; | 292 | LLVMValueRef llvm_global; |
| 292 | }; | 293 | }; |
| 293 | 294 | ||
| 295 | enum LazyValueId { | ||
| 296 | LazyValueIdInvalid, | ||
| 297 | LazyValueIdAlignOf, | ||
| 298 | LazyValueIdSliceType, | ||
| 299 | LazyValueIdFnType, | ||
| 300 | }; | ||
| 301 | |||
| 302 | struct LazyValue { | ||
| 303 | LazyValueId id; | ||
| 304 | IrExecutable *exec; | ||
| 305 | }; | ||
| 306 | |||
| 307 | struct LazyValueAlignOf { | ||
| 308 | LazyValue base; | ||
| 309 | ZigType *target_type; | ||
| 310 | }; | ||
| 311 | |||
| 312 | struct LazyValueSliceType { | ||
| 313 | LazyValue base; | ||
| 314 | ZigType *elem_type; | ||
| 315 | ConstExprValue *align_val; // can be null | ||
| 316 | bool is_const; | ||
| 317 | bool is_volatile; | ||
| 318 | bool is_allowzero; | ||
| 319 | }; | ||
| 320 | |||
| 321 | struct LazyValueFnType { | ||
| 322 | LazyValue base; | ||
| 323 | AstNode *proto_node; | ||
| 324 | ConstExprValue **param_types; | ||
| 325 | ConstExprValue *align_val; // can be null | ||
| 326 | ConstExprValue *return_type; | ||
| 327 | ConstExprValue *async_allocator_type; | ||
| 328 | bool is_generic; | ||
| 329 | bool is_var_args; | ||
| 330 | }; | ||
| 331 | |||
| 294 | struct ConstExprValue { | 332 | struct ConstExprValue { |
| 295 | ZigType *type; | 333 | ZigType *type; |
| 296 | ConstValSpecial special; | 334 | ConstValSpecial special; |
| ... | @@ -318,6 +356,7 @@ struct ConstExprValue { | ... | @@ -318,6 +356,7 @@ struct ConstExprValue { |
| 318 | ConstPtrValue x_ptr; | 356 | ConstPtrValue x_ptr; |
| 319 | ConstArgTuple x_arg_tuple; | 357 | ConstArgTuple x_arg_tuple; |
| 320 | Buf *x_enum_literal; | 358 | Buf *x_enum_literal; |
| 359 | LazyValue *x_lazy; | ||
| 321 | 360 | ||
| 322 | // populated if special == ConstValSpecialRuntime | 361 | // populated if special == ConstValSpecialRuntime |
| 323 | RuntimeHintErrorUnion rh_error_union; | 362 | RuntimeHintErrorUnion rh_error_union; |
| ... | @@ -359,6 +398,7 @@ enum TldResolution { | ... | @@ -359,6 +398,7 @@ enum TldResolution { |
| 359 | TldResolutionUnresolved, | 398 | TldResolutionUnresolved, |
| 360 | TldResolutionResolving, | 399 | TldResolutionResolving, |
| 361 | TldResolutionInvalid, | 400 | TldResolutionInvalid, |
| 401 | TldResolutionOkLazy, | ||
| 362 | TldResolutionOk, | 402 | TldResolutionOk, |
| 363 | }; | 403 | }; |
| 364 | 404 | ||
| ... | @@ -1064,7 +1104,8 @@ struct ZigTypeArray { | ... | @@ -1064,7 +1104,8 @@ struct ZigTypeArray { |
| 1064 | 1104 | ||
| 1065 | struct TypeStructField { | 1105 | struct TypeStructField { |
| 1066 | Buf *name; | 1106 | Buf *name; |
| 1067 | ZigType *type_entry; | 1107 | ZigType *type_entry; // available after ResolveStatusSizeKnown |
| 1108 | ConstExprValue *type_val; // available after ResolveStatusZeroBitsKnown | ||
| 1068 | size_t src_index; | 1109 | size_t src_index; |
| 1069 | size_t gen_index; | 1110 | size_t gen_index; |
| 1070 | size_t offset; // byte offset from beginning of struct | 1111 | size_t offset; // byte offset from beginning of struct |
| ... | @@ -1893,7 +1934,6 @@ struct ZigVar { | ... | @@ -1893,7 +1934,6 @@ struct ZigVar { |
| 1893 | AstNode *decl_node; | 1934 | AstNode *decl_node; |
| 1894 | ZigLLVMDILocalVariable *di_loc_var; | 1935 | ZigLLVMDILocalVariable *di_loc_var; |
| 1895 | size_t src_arg_index; | 1936 | size_t src_arg_index; |
| 1896 | size_t gen_arg_index; | ||
| 1897 | Scope *parent_scope; | 1937 | Scope *parent_scope; |
| 1898 | Scope *child_scope; | 1938 | Scope *child_scope; |
| 1899 | LLVMValueRef param_value_ref; | 1939 | LLVMValueRef param_value_ref; |
src/analyze.cpp+286-111| ... | @@ -19,7 +19,6 @@ | ... | @@ -19,7 +19,6 @@ |
| 19 | 19 | ||
| 20 | static const size_t default_backward_branch_quota = 1000; | 20 | static const size_t default_backward_branch_quota = 1000; |
| 21 | 21 | ||
| 22 | static Error resolve_enum_type(CodeGen *g, ZigType *enum_type); | ||
| 23 | static Error resolve_struct_type(CodeGen *g, ZigType *struct_type); | 22 | static Error resolve_struct_type(CodeGen *g, ZigType *struct_type); |
| 24 | 23 | ||
| 25 | static Error ATTRIBUTE_MUST_USE resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type); | 24 | static Error ATTRIBUTE_MUST_USE resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type); |
| ... | @@ -568,12 +567,11 @@ static size_t align_forward(size_t addr, size_t alignment) { | ... | @@ -568,12 +567,11 @@ static size_t align_forward(size_t addr, size_t alignment) { |
| 568 | return (addr + alignment - 1) & ~(alignment - 1); | 567 | return (addr + alignment - 1) & ~(alignment - 1); |
| 569 | } | 568 | } |
| 570 | 569 | ||
| 571 | static size_t next_field_offset(size_t offset, size_t align_from_zero, size_t field_size, size_t field_align) { | 570 | static size_t next_field_offset(size_t offset, size_t align_from_zero, size_t field_size, size_t next_field_align) { |
| 572 | BREAKPOINT; // TODO test this | ||
| 573 | // Convert offset to a pretend address which has the specified alignment. | 571 | // Convert offset to a pretend address which has the specified alignment. |
| 574 | size_t addr = offset + align_from_zero; | 572 | size_t addr = offset + align_from_zero; |
| 575 | // March the address forward to respect the field alignment. | 573 | // March the address forward to respect the field alignment. |
| 576 | size_t aligned_addr = align_forward(addr + field_size, field_align); | 574 | size_t aligned_addr = align_forward(addr + field_size, next_field_align); |
| 577 | // Convert back from pretend address to offset. | 575 | // Convert back from pretend address to offset. |
| 578 | return aligned_addr - align_from_zero; | 576 | return aligned_addr - align_from_zero; |
| 579 | } | 577 | } |
| ... | @@ -623,8 +621,8 @@ ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payloa | ... | @@ -623,8 +621,8 @@ ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payloa |
| 623 | field_aligns[err_union_err_index] = err_set_type->abi_align; | 621 | field_aligns[err_union_err_index] = err_set_type->abi_align; |
| 624 | field_sizes[err_union_payload_index] = payload_type->abi_size; | 622 | field_sizes[err_union_payload_index] = payload_type->abi_size; |
| 625 | field_aligns[err_union_payload_index] = payload_type->abi_align; | 623 | field_aligns[err_union_payload_index] = payload_type->abi_align; |
| 626 | size_t field2_offset = next_field_offset(0, entry->abi_align, field_sizes[0], field_aligns[0]); | 624 | size_t field2_offset = next_field_offset(0, entry->abi_align, field_sizes[0], field_aligns[1]); |
| 627 | entry->abi_size = next_field_offset(field2_offset, entry->abi_align, field_sizes[1], field_aligns[1]); | 625 | entry->abi_size = next_field_offset(field2_offset, entry->abi_align, field_sizes[1], entry->abi_align); |
| 628 | entry->size_in_bits = entry->abi_size * 8; | 626 | entry->size_in_bits = entry->abi_size * 8; |
| 629 | } | 627 | } |
| 630 | 628 | ||
| ... | @@ -699,6 +697,15 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) { | ... | @@ -699,6 +697,15 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) { |
| 699 | entry->data.structure.fields_by_name.put(ptr_field_name, &entry->data.structure.fields[slice_ptr_index]); | 697 | entry->data.structure.fields_by_name.put(ptr_field_name, &entry->data.structure.fields[slice_ptr_index]); |
| 700 | entry->data.structure.fields_by_name.put(len_field_name, &entry->data.structure.fields[slice_len_index]); | 698 | entry->data.structure.fields_by_name.put(len_field_name, &entry->data.structure.fields[slice_len_index]); |
| 701 | 699 | ||
| 700 | switch (type_requires_comptime(g, ptr_type)) { | ||
| 701 | case ReqCompTimeInvalid: | ||
| 702 | zig_unreachable(); | ||
| 703 | case ReqCompTimeNo: | ||
| 704 | break; | ||
| 705 | case ReqCompTimeYes: | ||
| 706 | entry->data.structure.requires_comptime = true; | ||
| 707 | } | ||
| 708 | |||
| 702 | if (!type_has_bits(ptr_type)) { | 709 | if (!type_has_bits(ptr_type)) { |
| 703 | entry->data.structure.gen_field_count = 1; | 710 | entry->data.structure.gen_field_count = 1; |
| 704 | entry->data.structure.fields[slice_ptr_index].gen_index = SIZE_MAX; | 711 | entry->data.structure.fields[slice_ptr_index].gen_index = SIZE_MAX; |
| ... | @@ -897,8 +904,8 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { | ... | @@ -897,8 +904,8 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { |
| 897 | 904 | ||
| 898 | fn_type->size_in_bits = g->builtin_types.entry_usize->size_in_bits; | 905 | fn_type->size_in_bits = g->builtin_types.entry_usize->size_in_bits; |
| 899 | fn_type->abi_size = g->builtin_types.entry_usize->abi_size; | 906 | fn_type->abi_size = g->builtin_types.entry_usize->abi_size; |
| 900 | fn_type->abi_align = (fn_type_id->alignment == 0) ? | 907 | // see also type_val_resolve_abi_align |
| 901 | g->builtin_types.entry_usize->abi_align : fn_type_id->alignment; | 908 | fn_type->abi_align = (fn_type_id->alignment == 0) ? 1 : fn_type_id->alignment; |
| 902 | 909 | ||
| 903 | g->fn_type_table.put(&fn_type->data.fn.fn_type_id, fn_type); | 910 | g->fn_type_table.put(&fn_type->data.fn.fn_type_id, fn_type); |
| 904 | 911 | ||
| ... | @@ -956,15 +963,134 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind | ... | @@ -956,15 +963,134 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind |
| 956 | return entry; | 963 | return entry; |
| 957 | } | 964 | } |
| 958 | 965 | ||
| 959 | static ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, | 966 | static ConstExprValue *analyze_const_value_allow_lazy(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, |
| 960 | Buf *type_name) | 967 | Buf *type_name, bool allow_lazy) |
| 961 | { | 968 | { |
| 962 | size_t backward_branch_count = 0; | 969 | size_t backward_branch_count = 0; |
| 963 | return ir_eval_const_value(g, scope, node, type_entry, | 970 | return ir_eval_const_value(g, scope, node, type_entry, |
| 964 | &backward_branch_count, default_backward_branch_quota, | 971 | &backward_branch_count, default_backward_branch_quota, |
| 965 | nullptr, nullptr, node, type_name, nullptr, nullptr); | 972 | nullptr, nullptr, node, type_name, nullptr, nullptr, allow_lazy); |
| 966 | } | 973 | } |
| 967 | 974 | ||
| 975 | static ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, | ||
| 976 | Buf *type_name) | ||
| 977 | { | ||
| 978 | return analyze_const_value_allow_lazy(g, scope, node, type_entry, type_name, false); | ||
| 979 | } | ||
| 980 | |||
| 981 | static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, bool *is_zero_bits) { | ||
| 982 | Error err; | ||
| 983 | if (type_val->special != ConstValSpecialLazy) { | ||
| 984 | assert(type_val->special == ConstValSpecialStatic); | ||
| 985 | if ((err = type_resolve(g, type_val->data.x_type, ResolveStatusZeroBitsKnown))) | ||
| 986 | return err; | ||
| 987 | *is_zero_bits = (type_val->data.x_type->abi_size == 0); | ||
| 988 | return ErrorNone; | ||
| 989 | } | ||
| 990 | switch (type_val->data.x_lazy->id) { | ||
| 991 | case LazyValueIdInvalid: | ||
| 992 | case LazyValueIdAlignOf: | ||
| 993 | zig_unreachable(); | ||
| 994 | case LazyValueIdSliceType: | ||
| 995 | *is_zero_bits = false; | ||
| 996 | return ErrorNone; | ||
| 997 | case LazyValueIdFnType: { | ||
| 998 | LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(type_val->data.x_lazy); | ||
| 999 | *is_zero_bits = lazy_fn_type->is_generic; | ||
| 1000 | return ErrorNone; | ||
| 1001 | } | ||
| 1002 | } | ||
| 1003 | zig_unreachable(); | ||
| 1004 | } | ||
| 1005 | |||
| 1006 | static Error type_val_resolve_is_opaque_type(CodeGen *g, ConstExprValue *type_val, bool *is_opaque_type) { | ||
| 1007 | if (type_val->special != ConstValSpecialLazy) { | ||
| 1008 | assert(type_val->special == ConstValSpecialStatic); | ||
| 1009 | *is_opaque_type = (type_val->data.x_type->id == ZigTypeIdOpaque); | ||
| 1010 | return ErrorNone; | ||
| 1011 | } | ||
| 1012 | switch (type_val->data.x_lazy->id) { | ||
| 1013 | case LazyValueIdInvalid: | ||
| 1014 | case LazyValueIdAlignOf: | ||
| 1015 | zig_unreachable(); | ||
| 1016 | case LazyValueIdSliceType: | ||
| 1017 | case LazyValueIdFnType: | ||
| 1018 | *is_opaque_type = false; | ||
| 1019 | return ErrorNone; | ||
| 1020 | } | ||
| 1021 | zig_unreachable(); | ||
| 1022 | } | ||
| 1023 | |||
| 1024 | static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue *type_val) { | ||
| 1025 | if (type_val->special != ConstValSpecialLazy) { | ||
| 1026 | return type_requires_comptime(g, type_val->data.x_type); | ||
| 1027 | } | ||
| 1028 | switch (type_val->data.x_lazy->id) { | ||
| 1029 | case LazyValueIdInvalid: | ||
| 1030 | case LazyValueIdAlignOf: | ||
| 1031 | zig_unreachable(); | ||
| 1032 | case LazyValueIdSliceType: { | ||
| 1033 | LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy); | ||
| 1034 | return type_requires_comptime(g, lazy_slice_type->elem_type); | ||
| 1035 | } | ||
| 1036 | case LazyValueIdFnType: { | ||
| 1037 | LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(type_val->data.x_lazy); | ||
| 1038 | if (lazy_fn_type->is_generic) | ||
| 1039 | return ReqCompTimeYes; | ||
| 1040 | switch (type_val_resolve_requires_comptime(g, lazy_fn_type->return_type)) { | ||
| 1041 | case ReqCompTimeInvalid: | ||
| 1042 | return ReqCompTimeInvalid; | ||
| 1043 | case ReqCompTimeYes: | ||
| 1044 | return ReqCompTimeYes; | ||
| 1045 | case ReqCompTimeNo: | ||
| 1046 | break; | ||
| 1047 | } | ||
| 1048 | size_t param_count = lazy_fn_type->proto_node->data.fn_proto.params.length; | ||
| 1049 | if (lazy_fn_type->is_var_args) param_count -= 1; | ||
| 1050 | for (size_t i = 0; i < param_count; i += 1) { | ||
| 1051 | switch (type_val_resolve_requires_comptime(g, lazy_fn_type->param_types[i])) { | ||
| 1052 | case ReqCompTimeInvalid: | ||
| 1053 | return ReqCompTimeInvalid; | ||
| 1054 | case ReqCompTimeYes: | ||
| 1055 | return ReqCompTimeYes; | ||
| 1056 | case ReqCompTimeNo: | ||
| 1057 | break; | ||
| 1058 | } | ||
| 1059 | } | ||
| 1060 | return ReqCompTimeNo; | ||
| 1061 | } | ||
| 1062 | } | ||
| 1063 | zig_unreachable(); | ||
| 1064 | } | ||
| 1065 | |||
| 1066 | static Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, size_t *abi_align) { | ||
| 1067 | Error err; | ||
| 1068 | if (type_val->special != ConstValSpecialLazy) { | ||
| 1069 | assert(type_val->special == ConstValSpecialStatic); | ||
| 1070 | if ((err = type_resolve(g, type_val->data.x_type, ResolveStatusAlignmentKnown))) | ||
| 1071 | return err; | ||
| 1072 | *abi_align = type_val->data.x_type->abi_align; | ||
| 1073 | return ErrorNone; | ||
| 1074 | } | ||
| 1075 | switch (type_val->data.x_lazy->id) { | ||
| 1076 | case LazyValueIdInvalid: | ||
| 1077 | case LazyValueIdAlignOf: | ||
| 1078 | zig_unreachable(); | ||
| 1079 | case LazyValueIdSliceType: | ||
| 1080 | *abi_align = g->builtin_types.entry_usize->abi_align; | ||
| 1081 | return ErrorNone; | ||
| 1082 | case LazyValueIdFnType: { | ||
| 1083 | LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(type_val->data.x_lazy); | ||
| 1084 | if (lazy_fn_type->align_val != nullptr) | ||
| 1085 | return type_val_resolve_abi_align(g, lazy_fn_type->align_val, abi_align); | ||
| 1086 | *abi_align = 1; | ||
| 1087 | return ErrorNone; | ||
| 1088 | } | ||
| 1089 | } | ||
| 1090 | zig_unreachable(); | ||
| 1091 | } | ||
| 1092 | |||
| 1093 | |||
| 968 | ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { | 1094 | ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { |
| 969 | ConstExprValue *result = analyze_const_value(g, scope, node, g->builtin_types.entry_type, nullptr); | 1095 | ConstExprValue *result = analyze_const_value(g, scope, node, g->builtin_types.entry_type, nullptr); |
| 970 | if (type_is_invalid(result->type)) | 1096 | if (type_is_invalid(result->type)) |
| ... | @@ -1492,11 +1618,6 @@ bool type_is_invalid(ZigType *type_entry) { | ... | @@ -1492,11 +1618,6 @@ bool type_is_invalid(ZigType *type_entry) { |
| 1492 | } | 1618 | } |
| 1493 | 1619 | ||
| 1494 | 1620 | ||
| 1495 | static Error resolve_enum_type(CodeGen *g, ZigType *enum_type) { | ||
| 1496 | return resolve_enum_zero_bits(g, enum_type); | ||
| 1497 | } | ||
| 1498 | |||
| 1499 | |||
| 1500 | ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[], | 1621 | ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[], |
| 1501 | ZigType *field_types[], size_t field_count) | 1622 | ZigType *field_types[], size_t field_count) |
| 1502 | { | 1623 | { |
| ... | @@ -1536,8 +1657,9 @@ ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_na | ... | @@ -1536,8 +1657,9 @@ ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_na |
| 1536 | for (size_t i = 0; i < field_count; i += 1) { | 1657 | for (size_t i = 0; i < field_count; i += 1) { |
| 1537 | TypeStructField *field = &struct_type->data.structure.fields[i]; | 1658 | TypeStructField *field = &struct_type->data.structure.fields[i]; |
| 1538 | field->offset = next_offset; | 1659 | field->offset = next_offset; |
| 1539 | next_offset = next_field_offset(next_offset, abi_align, | 1660 | size_t next_abi_align = (i + 1 == field_count) ? |
| 1540 | field->type_entry->abi_size, field->type_entry->abi_align); | 1661 | abi_align : struct_type->data.structure.fields[i + 1].type_entry->abi_align; |
| 1662 | next_offset = next_field_offset(next_offset, abi_align, field->type_entry->abi_size, next_abi_align); | ||
| 1541 | } | 1663 | } |
| 1542 | 1664 | ||
| 1543 | struct_type->abi_align = abi_align; | 1665 | struct_type->abi_align = abi_align; |
| ... | @@ -1548,7 +1670,7 @@ ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_na | ... | @@ -1548,7 +1670,7 @@ ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_na |
| 1548 | } | 1670 | } |
| 1549 | 1671 | ||
| 1550 | static size_t get_store_size_in_bits(size_t size_in_bits) { | 1672 | static size_t get_store_size_in_bits(size_t size_in_bits) { |
| 1551 | return (size_in_bits + 7) / 8; | 1673 | return ((size_in_bits + 7) / 8) * 8; |
| 1552 | } | 1674 | } |
| 1553 | 1675 | ||
| 1554 | static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { | 1676 | static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| ... | @@ -1584,7 +1706,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { | ... | @@ -1584,7 +1706,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| 1584 | bool packed = (struct_type->data.structure.layout == ContainerLayoutPacked); | 1706 | bool packed = (struct_type->data.structure.layout == ContainerLayoutPacked); |
| 1585 | struct_type->data.structure.resolve_loop_flag = true; | 1707 | struct_type->data.structure.resolve_loop_flag = true; |
| 1586 | 1708 | ||
| 1587 | uint32_t *host_int_bytes = allocate<uint32_t>(struct_type->data.structure.gen_field_count); | 1709 | uint32_t *host_int_bytes = packed ? allocate<uint32_t>(struct_type->data.structure.gen_field_count) : nullptr; |
| 1588 | 1710 | ||
| 1589 | // Compute offsets for all the fields. | 1711 | // Compute offsets for all the fields. |
| 1590 | size_t packed_bits_offset = 0; | 1712 | size_t packed_bits_offset = 0; |
| ... | @@ -1594,24 +1716,53 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { | ... | @@ -1594,24 +1716,53 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| 1594 | size_t size_in_bits = 0; | 1716 | size_t size_in_bits = 0; |
| 1595 | size_t abi_align = struct_type->abi_align; | 1717 | size_t abi_align = struct_type->abi_align; |
| 1596 | 1718 | ||
| 1719 | // Resolve types for fields | ||
| 1597 | for (size_t i = 0; i < field_count; i += 1) { | 1720 | for (size_t i = 0; i < field_count; i += 1) { |
| 1598 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; | 1721 | AstNode *field_source_node = decl_node->data.container_decl.fields.at(i); |
| 1599 | ZigType *field_type = type_struct_field->type_entry; | 1722 | TypeStructField *field = &struct_type->data.structure.fields[i]; |
| 1600 | 1723 | ||
| 1601 | if (!type_has_bits(field_type)) | 1724 | if ((err = ir_resolve_lazy(g, field_source_node, field->type_val))) { |
| 1602 | continue; | 1725 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 1726 | return err; | ||
| 1727 | } | ||
| 1728 | ZigType *field_type = field->type_val->data.x_type; | ||
| 1729 | field->type_entry = field_type; | ||
| 1603 | 1730 | ||
| 1604 | if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) { | 1731 | if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) { |
| 1605 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | 1732 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 1606 | return ErrorSemanticAnalyzeFail; | 1733 | return err; |
| 1607 | } | 1734 | } |
| 1608 | 1735 | ||
| 1609 | if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) { | 1736 | if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) { |
| 1610 | return ErrorSemanticAnalyzeFail; | 1737 | return ErrorSemanticAnalyzeFail; |
| 1611 | } | 1738 | } |
| 1612 | 1739 | ||
| 1613 | type_struct_field->gen_index = gen_field_index; | 1740 | if (packed) { |
| 1614 | type_struct_field->offset = next_offset; | 1741 | if ((err = emit_error_unless_type_allowed_in_packed_struct(g, field_type, field_source_node))) { |
| 1742 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | ||
| 1743 | return ErrorSemanticAnalyzeFail; | ||
| 1744 | } | ||
| 1745 | } else if (struct_type->data.structure.layout == ContainerLayoutExtern && | ||
| 1746 | !type_allowed_in_extern(g, field_type)) | ||
| 1747 | { | ||
| 1748 | add_node_error(g, field_source_node, | ||
| 1749 | buf_sprintf("extern structs cannot contain fields of type '%s'", | ||
| 1750 | buf_ptr(&field_type->name))); | ||
| 1751 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | ||
| 1752 | return ErrorSemanticAnalyzeFail; | ||
| 1753 | } | ||
| 1754 | } | ||
| 1755 | |||
| 1756 | // Calculate offsets | ||
| 1757 | for (size_t i = 0; i < field_count; i += 1) { | ||
| 1758 | TypeStructField *field = &struct_type->data.structure.fields[i]; | ||
| 1759 | if (field->gen_index == SIZE_MAX) | ||
| 1760 | continue; | ||
| 1761 | ZigType *field_type = field->type_entry; | ||
| 1762 | assert(field_type != nullptr); | ||
| 1763 | |||
| 1764 | field->gen_index = gen_field_index; | ||
| 1765 | field->offset = next_offset; | ||
| 1615 | 1766 | ||
| 1616 | if (packed) { | 1767 | if (packed) { |
| 1617 | size_t field_size_in_bits = type_size_bits(g, field_type); | 1768 | size_t field_size_in_bits = type_size_bits(g, field_type); |
| ... | @@ -1621,7 +1772,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { | ... | @@ -1621,7 +1772,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| 1621 | 1772 | ||
| 1622 | if (first_packed_bits_offset_misalign != SIZE_MAX) { | 1773 | if (first_packed_bits_offset_misalign != SIZE_MAX) { |
| 1623 | // this field is not byte-aligned; it is part of the previous field with a bit offset | 1774 | // this field is not byte-aligned; it is part of the previous field with a bit offset |
| 1624 | type_struct_field->bit_offset_in_host = packed_bits_offset - first_packed_bits_offset_misalign; | 1775 | field->bit_offset_in_host = packed_bits_offset - first_packed_bits_offset_misalign; |
| 1625 | 1776 | ||
| 1626 | size_t full_bit_count = next_packed_bits_offset - first_packed_bits_offset_misalign; | 1777 | size_t full_bit_count = next_packed_bits_offset - first_packed_bits_offset_misalign; |
| 1627 | if (get_store_size_in_bits(full_bit_count) == full_bit_count) { | 1778 | if (get_store_size_in_bits(full_bit_count) == full_bit_count) { |
| ... | @@ -1636,10 +1787,10 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { | ... | @@ -1636,10 +1787,10 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| 1636 | } | 1787 | } |
| 1637 | } else if (get_store_size_in_bits(field_type->size_in_bits) != field_size_in_bits) { | 1788 | } else if (get_store_size_in_bits(field_type->size_in_bits) != field_size_in_bits) { |
| 1638 | first_packed_bits_offset_misalign = packed_bits_offset; | 1789 | first_packed_bits_offset_misalign = packed_bits_offset; |
| 1639 | type_struct_field->bit_offset_in_host = 0; | 1790 | field->bit_offset_in_host = 0; |
| 1640 | } else { | 1791 | } else { |
| 1641 | // This is a byte-aligned field (both start and end) in a packed struct. | 1792 | // This is a byte-aligned field (both start and end) in a packed struct. |
| 1642 | type_struct_field->bit_offset_in_host = 0; | 1793 | field->bit_offset_in_host = 0; |
| 1643 | gen_field_index += 1; | 1794 | gen_field_index += 1; |
| 1644 | // TODO: https://github.com/ziglang/zig/issues/1512 | 1795 | // TODO: https://github.com/ziglang/zig/issues/1512 |
| 1645 | next_offset = next_field_offset(next_offset, abi_align, field_type->size_in_bits / 8, 1); | 1796 | next_offset = next_field_offset(next_offset, abi_align, field_type->size_in_bits / 8, 1); |
| ... | @@ -1648,7 +1799,15 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { | ... | @@ -1648,7 +1799,15 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| 1648 | packed_bits_offset = next_packed_bits_offset; | 1799 | packed_bits_offset = next_packed_bits_offset; |
| 1649 | } else { | 1800 | } else { |
| 1650 | gen_field_index += 1; | 1801 | gen_field_index += 1; |
| 1651 | next_offset = next_field_offset(next_offset, abi_align, field_type->abi_size, field_type->abi_align); | 1802 | size_t next_src_field_index = i + 1; |
| 1803 | for (; next_src_field_index < field_count; next_src_field_index += 1) { | ||
| 1804 | if (struct_type->data.structure.fields[next_src_field_index].gen_index != SIZE_MAX) { | ||
| 1805 | break; | ||
| 1806 | } | ||
| 1807 | } | ||
| 1808 | size_t next_abi_align = (next_src_field_index == field_count) ? | ||
| 1809 | abi_align : struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align; | ||
| 1810 | next_offset = next_field_offset(next_offset, abi_align, field_type->abi_size, next_abi_align); | ||
| 1652 | size_in_bits = next_offset * 8; | 1811 | size_in_bits = next_offset * 8; |
| 1653 | } | 1812 | } |
| 1654 | } | 1813 | } |
| ... | @@ -1679,9 +1838,10 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { | ... | @@ -1679,9 +1838,10 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { |
| 1679 | return ErrorSemanticAnalyzeFail; | 1838 | return ErrorSemanticAnalyzeFail; |
| 1680 | if (union_type->data.unionation.resolve_status >= ResolveStatusAlignmentKnown) | 1839 | if (union_type->data.unionation.resolve_status >= ResolveStatusAlignmentKnown) |
| 1681 | return ErrorNone; | 1840 | return ErrorNone; |
| 1682 | |||
| 1683 | if ((err = resolve_union_zero_bits(g, union_type))) | 1841 | if ((err = resolve_union_zero_bits(g, union_type))) |
| 1684 | return err; | 1842 | return err; |
| 1843 | if (union_type->data.unionation.resolve_status >= ResolveStatusAlignmentKnown) | ||
| 1844 | return ErrorNone; | ||
| 1685 | 1845 | ||
| 1686 | if (union_type->data.unionation.resolve_loop_flag) { | 1846 | if (union_type->data.unionation.resolve_loop_flag) { |
| 1687 | if (!union_type->data.unionation.reported_infinite_err) { | 1847 | if (!union_type->data.unionation.reported_infinite_err) { |
| ... | @@ -1724,7 +1884,7 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { | ... | @@ -1724,7 +1884,7 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { |
| 1724 | } | 1884 | } |
| 1725 | 1885 | ||
| 1726 | // unset temporary flag | 1886 | // unset temporary flag |
| 1727 | union_type->data.unionation.resolve_loop_flag = true; | 1887 | union_type->data.unionation.resolve_loop_flag = false; |
| 1728 | union_type->data.unionation.resolve_status = ResolveStatusAlignmentKnown; | 1888 | union_type->data.unionation.resolve_status = ResolveStatusAlignmentKnown; |
| 1729 | 1889 | ||
| 1730 | ZigType *tag_type = union_type->data.unionation.tag_type; | 1890 | ZigType *tag_type = union_type->data.unionation.tag_type; |
| ... | @@ -1836,8 +1996,8 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { | ... | @@ -1836,8 +1996,8 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { |
| 1836 | field_aligns[union_type->data.unionation.gen_tag_index] = tag_type->abi_align; | 1996 | field_aligns[union_type->data.unionation.gen_tag_index] = tag_type->abi_align; |
| 1837 | field_sizes[union_type->data.unionation.gen_union_index] = union_abi_size; | 1997 | field_sizes[union_type->data.unionation.gen_union_index] = union_abi_size; |
| 1838 | field_aligns[union_type->data.unionation.gen_union_index] = most_aligned_union_member->abi_align; | 1998 | field_aligns[union_type->data.unionation.gen_union_index] = most_aligned_union_member->abi_align; |
| 1839 | size_t field2_offset = next_field_offset(0, union_type->abi_align, field_sizes[0], field_aligns[0]); | 1999 | size_t field2_offset = next_field_offset(0, union_type->abi_align, field_sizes[0], field_aligns[1]); |
| 1840 | union_type->abi_size = next_field_offset(field2_offset, union_type->abi_align, field_sizes[1], field_aligns[1]); | 2000 | union_type->abi_size = next_field_offset(field2_offset, union_type->abi_align, field_sizes[1], union_type->abi_align); |
| 1841 | union_type->size_in_bits = union_type->abi_size * 8; | 2001 | union_type->size_in_bits = union_type->abi_size * 8; |
| 1842 | } | 2002 | } |
| 1843 | } else { | 2003 | } else { |
| ... | @@ -1928,6 +2088,9 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { | ... | @@ -1928,6 +2088,9 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 1928 | } | 2088 | } |
| 1929 | } | 2089 | } |
| 1930 | enum_type->data.enumeration.tag_int_type = tag_int_type; | 2090 | enum_type->data.enumeration.tag_int_type = tag_int_type; |
| 2091 | enum_type->size_in_bits = tag_int_type->size_in_bits; | ||
| 2092 | enum_type->abi_size = tag_int_type->abi_size; | ||
| 2093 | enum_type->abi_align = tag_int_type->abi_align; | ||
| 1931 | 2094 | ||
| 1932 | for (uint32_t field_i = 0; field_i < field_count; field_i += 1) { | 2095 | for (uint32_t field_i = 0; field_i < field_count; field_i += 1) { |
| 1933 | AstNode *field_node = decl_node->data.container_decl.fields.at(field_i); | 2096 | AstNode *field_node = decl_node->data.container_decl.fields.at(field_i); |
| ... | @@ -2012,6 +2175,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { | ... | @@ -2012,6 +2175,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2012 | 2175 | ||
| 2013 | enum_type->data.enumeration.zero_bits_loop_flag = false; | 2176 | enum_type->data.enumeration.zero_bits_loop_flag = false; |
| 2014 | enum_type->data.enumeration.zero_bits_known = true; | 2177 | enum_type->data.enumeration.zero_bits_known = true; |
| 2178 | enum_type->data.enumeration.complete = true; | ||
| 2015 | 2179 | ||
| 2016 | if (enum_type->data.enumeration.is_invalid) | 2180 | if (enum_type->data.enumeration.is_invalid) |
| 2017 | return ErrorSemanticAnalyzeFail; | 2181 | return ErrorSemanticAnalyzeFail; |
| ... | @@ -2022,22 +2186,28 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { | ... | @@ -2022,22 +2186,28 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2022 | static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { | 2186 | static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { |
| 2023 | assert(struct_type->id == ZigTypeIdStruct); | 2187 | assert(struct_type->id == ZigTypeIdStruct); |
| 2024 | 2188 | ||
| 2189 | Error err; | ||
| 2190 | |||
| 2025 | if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) | 2191 | if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) |
| 2026 | return ErrorSemanticAnalyzeFail; | 2192 | return ErrorSemanticAnalyzeFail; |
| 2027 | if (struct_type->data.structure.resolve_status >= ResolveStatusZeroBitsKnown) | 2193 | if (struct_type->data.structure.resolve_status >= ResolveStatusZeroBitsKnown) |
| 2028 | return ErrorNone; | 2194 | return ErrorNone; |
| 2029 | 2195 | ||
| 2196 | AstNode *decl_node = struct_type->data.structure.decl_node; | ||
| 2197 | assert(decl_node->type == NodeTypeContainerDecl); | ||
| 2198 | |||
| 2030 | if (struct_type->data.structure.resolve_loop_flag) { | 2199 | if (struct_type->data.structure.resolve_loop_flag) { |
| 2031 | struct_type->data.structure.resolve_status = ResolveStatusZeroBitsKnown; | 2200 | if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) { |
| 2032 | struct_type->data.structure.resolve_loop_flag = false; | 2201 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2033 | return ErrorNone; | 2202 | ErrorMsg *msg = add_node_error(g, decl_node, |
| 2203 | buf_sprintf("struct '%s' depends on its own size", buf_ptr(&struct_type->name))); | ||
| 2204 | emit_error_notes_for_ref_stack(g, msg); | ||
| 2205 | } | ||
| 2206 | return ErrorSemanticAnalyzeFail; | ||
| 2034 | } | 2207 | } |
| 2035 | 2208 | ||
| 2036 | struct_type->data.structure.resolve_loop_flag = true; | 2209 | struct_type->data.structure.resolve_loop_flag = true; |
| 2037 | 2210 | ||
| 2038 | AstNode *decl_node = struct_type->data.structure.decl_node; | ||
| 2039 | assert(decl_node->type == NodeTypeContainerDecl); | ||
| 2040 | |||
| 2041 | assert(!struct_type->data.structure.fields); | 2211 | assert(!struct_type->data.structure.fields); |
| 2042 | size_t field_count = decl_node->data.container_decl.fields.length; | 2212 | size_t field_count = decl_node->data.container_decl.fields.length; |
| 2043 | struct_type->data.structure.src_field_count = (uint32_t)field_count; | 2213 | struct_type->data.structure.src_field_count = (uint32_t)field_count; |
| ... | @@ -2056,7 +2226,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { | ... | @@ -2056,7 +2226,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { |
| 2056 | if (field_node->data.struct_field.type == nullptr) { | 2226 | if (field_node->data.struct_field.type == nullptr) { |
| 2057 | add_node_error(g, field_node, buf_sprintf("struct field missing type")); | 2227 | add_node_error(g, field_node, buf_sprintf("struct field missing type")); |
| 2058 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | 2228 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2059 | continue; | 2229 | return ErrorSemanticAnalyzeFail; |
| 2060 | } | 2230 | } |
| 2061 | 2231 | ||
| 2062 | auto field_entry = struct_type->data.structure.fields_by_name.put_unique(type_struct_field->name, type_struct_field); | 2232 | auto field_entry = struct_type->data.structure.fields_by_name.put_unique(type_struct_field->name, type_struct_field); |
| ... | @@ -2065,38 +2235,55 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { | ... | @@ -2065,38 +2235,55 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { |
| 2065 | buf_sprintf("duplicate struct field: '%s'", buf_ptr(type_struct_field->name))); | 2235 | buf_sprintf("duplicate struct field: '%s'", buf_ptr(type_struct_field->name))); |
| 2066 | add_error_note(g, msg, field_entry->value->decl_node, buf_sprintf("other field here")); | 2236 | add_error_note(g, msg, field_entry->value->decl_node, buf_sprintf("other field here")); |
| 2067 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | 2237 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2068 | continue; | 2238 | return ErrorSemanticAnalyzeFail; |
| 2069 | } | 2239 | } |
| 2070 | 2240 | ||
| 2071 | ZigType *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type); | 2241 | ConstExprValue *field_type_val = analyze_const_value_allow_lazy(g, scope, |
| 2072 | type_struct_field->type_entry = field_type; | 2242 | field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, true); |
| 2243 | if (type_is_invalid(field_type_val->type)) { | ||
| 2244 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | ||
| 2245 | return ErrorSemanticAnalyzeFail; | ||
| 2246 | } | ||
| 2247 | assert(field_type_val->special != ConstValSpecialRuntime); | ||
| 2248 | type_struct_field->type_val = field_type_val; | ||
| 2073 | type_struct_field->src_index = i; | 2249 | type_struct_field->src_index = i; |
| 2074 | type_struct_field->gen_index = SIZE_MAX; | 2250 | type_struct_field->gen_index = SIZE_MAX; |
| 2075 | 2251 | ||
| 2252 | if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) | ||
| 2253 | return ErrorSemanticAnalyzeFail; | ||
| 2254 | |||
| 2076 | if (field_node->data.struct_field.value != nullptr) { | 2255 | if (field_node->data.struct_field.value != nullptr) { |
| 2077 | add_node_error(g, field_node->data.struct_field.value, | 2256 | add_node_error(g, field_node->data.struct_field.value, |
| 2078 | buf_sprintf("enums, not structs, support field assignment")); | 2257 | buf_sprintf("enums, not structs, support field assignment")); |
| 2079 | } | 2258 | } |
| 2080 | 2259 | bool field_is_opaque_type; | |
| 2081 | if (field_type->id == ZigTypeIdOpaque) { | 2260 | if ((err = type_val_resolve_is_opaque_type(g, field_type_val, &field_is_opaque_type))) { |
| 2261 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | ||
| 2262 | return ErrorSemanticAnalyzeFail; | ||
| 2263 | } | ||
| 2264 | if (field_is_opaque_type) { | ||
| 2082 | add_node_error(g, field_node->data.struct_field.type, | 2265 | add_node_error(g, field_node->data.struct_field.type, |
| 2083 | buf_sprintf("opaque types have unknown size and therefore cannot be directly embedded in structs")); | 2266 | buf_sprintf("opaque types have unknown size and therefore cannot be directly embedded in structs")); |
| 2084 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | 2267 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2085 | continue; | 2268 | return ErrorSemanticAnalyzeFail; |
| 2086 | } | 2269 | } |
| 2087 | 2270 | switch (type_val_resolve_requires_comptime(g, field_type_val)) { | |
| 2088 | switch (type_requires_comptime(g, field_type)) { | ||
| 2089 | case ReqCompTimeYes: | 2271 | case ReqCompTimeYes: |
| 2090 | struct_type->data.structure.requires_comptime = true; | 2272 | struct_type->data.structure.requires_comptime = true; |
| 2091 | break; | 2273 | break; |
| 2092 | case ReqCompTimeInvalid: | 2274 | case ReqCompTimeInvalid: |
| 2093 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | 2275 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2094 | continue; | 2276 | return ErrorSemanticAnalyzeFail; |
| 2095 | case ReqCompTimeNo: | 2277 | case ReqCompTimeNo: |
| 2096 | break; | 2278 | break; |
| 2097 | } | 2279 | } |
| 2098 | 2280 | ||
| 2099 | if (!type_has_bits(field_type)) | 2281 | bool field_is_zero_bits; |
| 2282 | if ((err = type_val_resolve_zero_bits(g, field_type_val, &field_is_zero_bits))) { | ||
| 2283 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | ||
| 2284 | return ErrorSemanticAnalyzeFail; | ||
| 2285 | } | ||
| 2286 | if (field_is_zero_bits) | ||
| 2100 | continue; | 2287 | continue; |
| 2101 | 2288 | ||
| 2102 | type_struct_field->gen_index = gen_field_index; | 2289 | type_struct_field->gen_index = gen_field_index; |
| ... | @@ -2126,9 +2313,10 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { | ... | @@ -2126,9 +2313,10 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { |
| 2126 | return ErrorSemanticAnalyzeFail; | 2313 | return ErrorSemanticAnalyzeFail; |
| 2127 | if (struct_type->data.structure.resolve_status >= ResolveStatusAlignmentKnown) | 2314 | if (struct_type->data.structure.resolve_status >= ResolveStatusAlignmentKnown) |
| 2128 | return ErrorNone; | 2315 | return ErrorNone; |
| 2129 | |||
| 2130 | if ((err = resolve_struct_zero_bits(g, struct_type))) | 2316 | if ((err = resolve_struct_zero_bits(g, struct_type))) |
| 2131 | return err; | 2317 | return err; |
| 2318 | if (struct_type->data.structure.resolve_status >= ResolveStatusAlignmentKnown) | ||
| 2319 | return ErrorNone; | ||
| 2132 | 2320 | ||
| 2133 | AstNode *decl_node = struct_type->data.structure.decl_node; | 2321 | AstNode *decl_node = struct_type->data.structure.decl_node; |
| 2134 | 2322 | ||
| ... | @@ -2136,7 +2324,7 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { | ... | @@ -2136,7 +2324,7 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { |
| 2136 | if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) { | 2324 | if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) { |
| 2137 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | 2325 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2138 | ErrorMsg *msg = add_node_error(g, decl_node, | 2326 | ErrorMsg *msg = add_node_error(g, decl_node, |
| 2139 | buf_sprintf("struct '%s' contains itself", buf_ptr(&struct_type->name))); | 2327 | buf_sprintf("struct '%s' depends on its own alignment", buf_ptr(&struct_type->name))); |
| 2140 | emit_error_notes_for_ref_stack(g, msg); | 2328 | emit_error_notes_for_ref_stack(g, msg); |
| 2141 | } | 2329 | } |
| 2142 | return ErrorSemanticAnalyzeFail; | 2330 | return ErrorSemanticAnalyzeFail; |
| ... | @@ -2151,42 +2339,23 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { | ... | @@ -2151,42 +2339,23 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { |
| 2151 | 2339 | ||
| 2152 | for (size_t i = 0; i < field_count; i += 1) { | 2340 | for (size_t i = 0; i < field_count; i += 1) { |
| 2153 | TypeStructField *field = &struct_type->data.structure.fields[i]; | 2341 | TypeStructField *field = &struct_type->data.structure.fields[i]; |
| 2154 | ZigType *field_type = field->type_entry; | 2342 | if (field->gen_index == SIZE_MAX) |
| 2155 | assert(field_type != nullptr); | ||
| 2156 | |||
| 2157 | if ((err = type_resolve(g, field_type, ResolveStatusAlignmentKnown))) { | ||
| 2158 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | ||
| 2159 | return ErrorSemanticAnalyzeFail; | ||
| 2160 | } | ||
| 2161 | |||
| 2162 | if (struct_type->data.structure.layout == ContainerLayoutExtern && | ||
| 2163 | !type_allowed_in_extern(g, field_type)) | ||
| 2164 | { | ||
| 2165 | AstNode *field_source_node = decl_node->data.container_decl.fields.at(i); | ||
| 2166 | add_node_error(g, field_source_node, | ||
| 2167 | buf_sprintf("extern structs cannot contain fields of type '%s'", | ||
| 2168 | buf_ptr(&field_type->name))); | ||
| 2169 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | ||
| 2170 | return ErrorSemanticAnalyzeFail; | ||
| 2171 | } | ||
| 2172 | |||
| 2173 | if (!type_has_bits(field_type)) | ||
| 2174 | continue; | 2343 | continue; |
| 2175 | 2344 | ||
| 2176 | if (packed) { | 2345 | if (packed) { |
| 2177 | AstNode *field_source_node = decl_node->data.container_decl.fields.at(i); | ||
| 2178 | if ((err = emit_error_unless_type_allowed_in_packed_struct(g, field_type, field_source_node))) { | ||
| 2179 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | ||
| 2180 | return ErrorSemanticAnalyzeFail; | ||
| 2181 | } | ||
| 2182 | // TODO: https://github.com/ziglang/zig/issues/1512 | 2346 | // TODO: https://github.com/ziglang/zig/issues/1512 |
| 2183 | if (1 > abi_align) { | 2347 | if (1 > abi_align) { |
| 2184 | abi_align = 1; | 2348 | abi_align = 1; |
| 2185 | } | 2349 | } |
| 2186 | } else { | 2350 | } else { |
| 2187 | // TODO: https://github.com/ziglang/zig/issues/1512 | 2351 | // TODO: https://github.com/ziglang/zig/issues/1512 |
| 2188 | if (field_type->abi_align > abi_align) { | 2352 | size_t field_align; |
| 2189 | abi_align = field_type->abi_align; | 2353 | if ((err = type_val_resolve_abi_align(g, field->type_val, &field_align))) { |
| 2354 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | ||
| 2355 | return err; | ||
| 2356 | } | ||
| 2357 | if (field_align > abi_align) { | ||
| 2358 | abi_align = field_align; | ||
| 2190 | } | 2359 | } |
| 2191 | } | 2360 | } |
| 2192 | } | 2361 | } |
| ... | @@ -2824,7 +2993,7 @@ void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source | ... | @@ -2824,7 +2993,7 @@ void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source |
| 2824 | 2993 | ||
| 2825 | void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value) { | 2994 | void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value) { |
| 2826 | Tld *tld = get_container_scope(g->compile_var_import)->decl_table.get(name); | 2995 | Tld *tld = get_container_scope(g->compile_var_import)->decl_table.get(name); |
| 2827 | resolve_top_level_decl(g, tld, tld->source_node); | 2996 | resolve_top_level_decl(g, tld, tld->source_node, false); |
| 2828 | assert(tld->id == TldIdVar); | 2997 | assert(tld->id == TldIdVar); |
| 2829 | TldVar *tld_var = (TldVar *)tld; | 2998 | TldVar *tld_var = (TldVar *)tld; |
| 2830 | tld_var->var->const_value = value; | 2999 | tld_var->var->const_value = value; |
| ... | @@ -2933,20 +3102,17 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { | ... | @@ -2933,20 +3102,17 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { |
| 2933 | } | 3102 | } |
| 2934 | } | 3103 | } |
| 2935 | 3104 | ||
| 2936 | static void resolve_decl_container(CodeGen *g, TldContainer *tld_container) { | 3105 | static Error resolve_decl_container(CodeGen *g, TldContainer *tld_container) { |
| 2937 | ZigType *type_entry = tld_container->type_entry; | 3106 | ZigType *type_entry = tld_container->type_entry; |
| 2938 | assert(type_entry); | 3107 | assert(type_entry); |
| 2939 | 3108 | ||
| 2940 | switch (type_entry->id) { | 3109 | switch (type_entry->id) { |
| 2941 | case ZigTypeIdStruct: | 3110 | case ZigTypeIdStruct: |
| 2942 | resolve_struct_type(g, tld_container->type_entry); | 3111 | return resolve_struct_type(g, tld_container->type_entry); |
| 2943 | return; | ||
| 2944 | case ZigTypeIdEnum: | 3112 | case ZigTypeIdEnum: |
| 2945 | resolve_enum_type(g, tld_container->type_entry); | 3113 | return resolve_enum_zero_bits(g, tld_container->type_entry); |
| 2946 | return; | ||
| 2947 | case ZigTypeIdUnion: | 3114 | case ZigTypeIdUnion: |
| 2948 | resolve_union_type(g, tld_container->type_entry); | 3115 | return resolve_union_type(g, tld_container->type_entry); |
| 2949 | return; | ||
| 2950 | default: | 3116 | default: |
| 2951 | zig_unreachable(); | 3117 | zig_unreachable(); |
| 2952 | } | 3118 | } |
| ... | @@ -3066,7 +3232,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf | ... | @@ -3066,7 +3232,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf |
| 3066 | return variable_entry; | 3232 | return variable_entry; |
| 3067 | } | 3233 | } |
| 3068 | 3234 | ||
| 3069 | static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { | 3235 | static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) { |
| 3070 | AstNode *source_node = tld_var->base.source_node; | 3236 | AstNode *source_node = tld_var->base.source_node; |
| 3071 | AstNodeVariableDeclaration *var_decl = &source_node->data.variable_declaration; | 3237 | AstNodeVariableDeclaration *var_decl = &source_node->data.variable_declaration; |
| 3072 | 3238 | ||
| ... | @@ -3107,7 +3273,8 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { | ... | @@ -3107,7 +3273,8 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { |
| 3107 | if (explicit_type && explicit_type->id == ZigTypeIdInvalid) { | 3273 | if (explicit_type && explicit_type->id == ZigTypeIdInvalid) { |
| 3108 | implicit_type = explicit_type; | 3274 | implicit_type = explicit_type; |
| 3109 | } else if (var_decl->expr) { | 3275 | } else if (var_decl->expr) { |
| 3110 | init_value = analyze_const_value(g, tld_var->base.parent_scope, var_decl->expr, explicit_type, var_decl->symbol); | 3276 | init_value = analyze_const_value_allow_lazy(g, tld_var->base.parent_scope, var_decl->expr, |
| 3277 | explicit_type, var_decl->symbol, allow_lazy); | ||
| 3111 | assert(init_value); | 3278 | assert(init_value); |
| 3112 | implicit_type = init_value->type; | 3279 | implicit_type = init_value->type; |
| 3113 | 3280 | ||
| ... | @@ -3170,11 +3337,11 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { | ... | @@ -3170,11 +3337,11 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { |
| 3170 | g->global_vars.append(tld_var); | 3337 | g->global_vars.append(tld_var); |
| 3171 | } | 3338 | } |
| 3172 | 3339 | ||
| 3173 | void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) { | 3340 | void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node, bool allow_lazy) { |
| 3174 | if (tld->resolution != TldResolutionUnresolved) | 3341 | bool want_resolve_lazy = tld->resolution == TldResolutionOkLazy && !allow_lazy; |
| 3342 | if (tld->resolution != TldResolutionUnresolved && !want_resolve_lazy) | ||
| 3175 | return; | 3343 | return; |
| 3176 | 3344 | ||
| 3177 | assert(tld->resolution != TldResolutionResolving); | ||
| 3178 | tld->resolution = TldResolutionResolving; | 3345 | tld->resolution = TldResolutionResolving; |
| 3179 | g->tld_ref_source_node_stack.append(source_node); | 3346 | g->tld_ref_source_node_stack.append(source_node); |
| 3180 | 3347 | ||
| ... | @@ -3182,7 +3349,11 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) { | ... | @@ -3182,7 +3349,11 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) { |
| 3182 | case TldIdVar: | 3349 | case TldIdVar: |
| 3183 | { | 3350 | { |
| 3184 | TldVar *tld_var = (TldVar *)tld; | 3351 | TldVar *tld_var = (TldVar *)tld; |
| 3185 | resolve_decl_var(g, tld_var); | 3352 | if (want_resolve_lazy) { |
| 3353 | ir_resolve_lazy(g, source_node, tld_var->var->const_value); | ||
| 3354 | } else { | ||
| 3355 | resolve_decl_var(g, tld_var, allow_lazy); | ||
| 3356 | } | ||
| 3186 | break; | 3357 | break; |
| 3187 | } | 3358 | } |
| 3188 | case TldIdFn: | 3359 | case TldIdFn: |
| ... | @@ -3205,7 +3376,7 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) { | ... | @@ -3205,7 +3376,7 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) { |
| 3205 | } | 3376 | } |
| 3206 | } | 3377 | } |
| 3207 | 3378 | ||
| 3208 | tld->resolution = TldResolutionOk; | 3379 | tld->resolution = allow_lazy ? TldResolutionOkLazy : TldResolutionOk; |
| 3209 | g->tld_ref_source_node_stack.pop(); | 3380 | g->tld_ref_source_node_stack.pop(); |
| 3210 | } | 3381 | } |
| 3211 | 3382 | ||
| ... | @@ -3399,17 +3570,14 @@ ZigType *container_ref_type(ZigType *type_entry) { | ... | @@ -3399,17 +3570,14 @@ ZigType *container_ref_type(ZigType *type_entry) { |
| 3399 | type_entry->data.pointer.child_type : type_entry; | 3570 | type_entry->data.pointer.child_type : type_entry; |
| 3400 | } | 3571 | } |
| 3401 | 3572 | ||
| 3402 | void resolve_container_type(CodeGen *g, ZigType *type_entry) { | 3573 | Error resolve_container_type(CodeGen *g, ZigType *type_entry) { |
| 3403 | switch (type_entry->id) { | 3574 | switch (type_entry->id) { |
| 3404 | case ZigTypeIdStruct: | 3575 | case ZigTypeIdStruct: |
| 3405 | resolve_struct_type(g, type_entry); | 3576 | return resolve_struct_type(g, type_entry); |
| 3406 | break; | ||
| 3407 | case ZigTypeIdEnum: | 3577 | case ZigTypeIdEnum: |
| 3408 | resolve_enum_type(g, type_entry); | 3578 | return resolve_enum_zero_bits(g, type_entry); |
| 3409 | break; | ||
| 3410 | case ZigTypeIdUnion: | 3579 | case ZigTypeIdUnion: |
| 3411 | resolve_union_type(g, type_entry); | 3580 | return resolve_union_type(g, type_entry); |
| 3412 | break; | ||
| 3413 | case ZigTypeIdPointer: | 3581 | case ZigTypeIdPointer: |
| 3414 | case ZigTypeIdMetaType: | 3582 | case ZigTypeIdMetaType: |
| 3415 | case ZigTypeIdVoid: | 3583 | case ZigTypeIdVoid: |
| ... | @@ -3435,6 +3603,7 @@ void resolve_container_type(CodeGen *g, ZigType *type_entry) { | ... | @@ -3435,6 +3603,7 @@ void resolve_container_type(CodeGen *g, ZigType *type_entry) { |
| 3435 | case ZigTypeIdVector: | 3603 | case ZigTypeIdVector: |
| 3436 | zig_unreachable(); | 3604 | zig_unreachable(); |
| 3437 | } | 3605 | } |
| 3606 | zig_unreachable(); | ||
| 3438 | } | 3607 | } |
| 3439 | 3608 | ||
| 3440 | ZigType *get_src_ptr_type(ZigType *type) { | 3609 | ZigType *get_src_ptr_type(ZigType *type) { |
| ... | @@ -3536,10 +3705,6 @@ static void define_local_param_variables(CodeGen *g, ZigFn *fn_table_entry) { | ... | @@ -3536,10 +3705,6 @@ static void define_local_param_variables(CodeGen *g, ZigFn *fn_table_entry) { |
| 3536 | if (type_has_bits(param_type)) { | 3705 | if (type_has_bits(param_type)) { |
| 3537 | fn_table_entry->variable_list.append(var); | 3706 | fn_table_entry->variable_list.append(var); |
| 3538 | } | 3707 | } |
| 3539 | |||
| 3540 | if (fn_type->data.fn.gen_param_info) { | ||
| 3541 | var->gen_arg_index = fn_type->data.fn.gen_param_info[i].gen_index; | ||
| 3542 | } | ||
| 3543 | } | 3708 | } |
| 3544 | } | 3709 | } |
| 3545 | 3710 | ||
| ... | @@ -3880,7 +4045,7 @@ void semantic_analyze(CodeGen *g) { | ... | @@ -3880,7 +4045,7 @@ void semantic_analyze(CodeGen *g) { |
| 3880 | for (; g->resolve_queue_index < g->resolve_queue.length; g->resolve_queue_index += 1) { | 4045 | for (; g->resolve_queue_index < g->resolve_queue.length; g->resolve_queue_index += 1) { |
| 3881 | Tld *tld = g->resolve_queue.at(g->resolve_queue_index); | 4046 | Tld *tld = g->resolve_queue.at(g->resolve_queue_index); |
| 3882 | AstNode *source_node = nullptr; | 4047 | AstNode *source_node = nullptr; |
| 3883 | resolve_top_level_decl(g, tld, source_node); | 4048 | resolve_top_level_decl(g, tld, source_node, false); |
| 3884 | } | 4049 | } |
| 3885 | 4050 | ||
| 3886 | for (; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) { | 4051 | for (; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) { |
| ... | @@ -4941,7 +5106,7 @@ Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) { | ... | @@ -4941,7 +5106,7 @@ Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) { |
| 4941 | if (ty->id == ZigTypeIdStruct) { | 5106 | if (ty->id == ZigTypeIdStruct) { |
| 4942 | return resolve_struct_type(g, ty); | 5107 | return resolve_struct_type(g, ty); |
| 4943 | } else if (ty->id == ZigTypeIdEnum) { | 5108 | } else if (ty->id == ZigTypeIdEnum) { |
| 4944 | return resolve_enum_type(g, ty); | 5109 | return resolve_enum_zero_bits(g, ty); |
| 4945 | } else if (ty->id == ZigTypeIdUnion) { | 5110 | } else if (ty->id == ZigTypeIdUnion) { |
| 4946 | return resolve_union_type(g, ty); | 5111 | return resolve_union_type(g, ty); |
| 4947 | } | 5112 | } |
| ... | @@ -5314,6 +5479,9 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { | ... | @@ -5314,6 +5479,9 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { |
| 5314 | case ConstValSpecialRuntime: | 5479 | case ConstValSpecialRuntime: |
| 5315 | buf_appendf(buf, "(runtime value)"); | 5480 | buf_appendf(buf, "(runtime value)"); |
| 5316 | return; | 5481 | return; |
| 5482 | case ConstValSpecialLazy: | ||
| 5483 | buf_appendf(buf, "(lazy value)"); | ||
| 5484 | return; | ||
| 5317 | case ConstValSpecialUndef: | 5485 | case ConstValSpecialUndef: |
| 5318 | buf_appendf(buf, "undefined"); | 5486 | buf_appendf(buf, "undefined"); |
| 5319 | return; | 5487 | return; |
| ... | @@ -5930,7 +6098,7 @@ bool type_ptr_eql(const ZigType *a, const ZigType *b) { | ... | @@ -5930,7 +6098,7 @@ bool type_ptr_eql(const ZigType *a, const ZigType *b) { |
| 5930 | 6098 | ||
| 5931 | ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name) { | 6099 | ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name) { |
| 5932 | Tld *tld = get_container_scope(codegen->compile_var_import)->decl_table.get(buf_create_from_str(name)); | 6100 | Tld *tld = get_container_scope(codegen->compile_var_import)->decl_table.get(buf_create_from_str(name)); |
| 5933 | resolve_top_level_decl(codegen, tld, nullptr); | 6101 | resolve_top_level_decl(codegen, tld, nullptr, false); |
| 5934 | assert(tld->id == TldIdVar); | 6102 | assert(tld->id == TldIdVar); |
| 5935 | TldVar *tld_var = (TldVar *)tld; | 6103 | TldVar *tld_var = (TldVar *)tld; |
| 5936 | ConstExprValue *var_value = tld_var->var->const_value; | 6104 | ConstExprValue *var_value = tld_var->var->const_value; |
| ... | @@ -6114,6 +6282,8 @@ bool type_is_c_abi_int(CodeGen *g, ZigType *ty) { | ... | @@ -6114,6 +6282,8 @@ bool type_is_c_abi_int(CodeGen *g, ZigType *ty) { |
| 6114 | uint32_t get_host_int_bytes(CodeGen *g, ZigType *struct_type, TypeStructField *field) { | 6282 | uint32_t get_host_int_bytes(CodeGen *g, ZigType *struct_type, TypeStructField *field) { |
| 6115 | assert(struct_type->id == ZigTypeIdStruct); | 6283 | assert(struct_type->id == ZigTypeIdStruct); |
| 6116 | assert(type_is_resolved(struct_type, ResolveStatusSizeKnown)); | 6284 | assert(type_is_resolved(struct_type, ResolveStatusSizeKnown)); |
| 6285 | if (struct_type->data.structure.host_int_bytes == nullptr) | ||
| 6286 | return 0; | ||
| 6117 | return struct_type->data.structure.host_int_bytes[field->gen_index]; | 6287 | return struct_type->data.structure.host_int_bytes[field->gen_index]; |
| 6118 | } | 6288 | } |
| 6119 | 6289 | ||
| ... | @@ -6374,8 +6544,13 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) { | ... | @@ -6374,8 +6544,13 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) { |
| 6374 | LLVMStructSetBody(struct_type->llvm_type, element_types, (unsigned)gen_field_count, packed); | 6544 | LLVMStructSetBody(struct_type->llvm_type, element_types, (unsigned)gen_field_count, packed); |
| 6375 | 6545 | ||
| 6376 | ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(debug_field_count); | 6546 | ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(debug_field_count); |
| 6377 | |||
| 6378 | ZigType *import = get_scope_import(scope); | 6547 | ZigType *import = get_scope_import(scope); |
| 6548 | unsigned dwarf_kind = ZigLLVMTag_DW_structure_type(); | ||
| 6549 | struct_type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, | ||
| 6550 | dwarf_kind, buf_ptr(&struct_type->name), | ||
| 6551 | ZigLLVMFileToScope(import->data.structure.root_struct->di_file), | ||
| 6552 | import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1)); | ||
| 6553 | |||
| 6379 | size_t debug_field_index = 0; | 6554 | size_t debug_field_index = 0; |
| 6380 | for (size_t i = 0; i < field_count; i += 1) { | 6555 | for (size_t i = 0; i < field_count; i += 1) { |
| 6381 | AstNode *field_node = decl_node->data.container_decl.fields.at(i); | 6556 | AstNode *field_node = decl_node->data.container_decl.fields.at(i); |
src/analyze.hpp+3-2| ... | @@ -61,7 +61,7 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *abs_full_path, Bu | ... | @@ -61,7 +61,7 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *abs_full_path, Bu |
| 61 | ZigVar *find_variable(CodeGen *g, Scope *orig_context, Buf *name, ScopeFnDef **crossed_fndef_scope); | 61 | ZigVar *find_variable(CodeGen *g, Scope *orig_context, Buf *name, ScopeFnDef **crossed_fndef_scope); |
| 62 | Tld *find_decl(CodeGen *g, Scope *scope, Buf *name); | 62 | Tld *find_decl(CodeGen *g, Scope *scope, Buf *name); |
| 63 | Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name); | 63 | Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name); |
| 64 | void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node); | 64 | void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node, bool allow_lazy); |
| 65 | 65 | ||
| 66 | ZigType *get_src_ptr_type(ZigType *type); | 66 | ZigType *get_src_ptr_type(ZigType *type); |
| 67 | ZigType *get_codegen_ptr_type(ZigType *type); | 67 | ZigType *get_codegen_ptr_type(ZigType *type); |
| ... | @@ -73,7 +73,7 @@ bool type_is_complete(ZigType *type_entry); | ... | @@ -73,7 +73,7 @@ bool type_is_complete(ZigType *type_entry); |
| 73 | bool type_is_resolved(ZigType *type_entry, ResolveStatus status); | 73 | bool type_is_resolved(ZigType *type_entry, ResolveStatus status); |
| 74 | bool type_is_invalid(ZigType *type_entry); | 74 | bool type_is_invalid(ZigType *type_entry); |
| 75 | bool type_is_global_error_set(ZigType *err_set_type); | 75 | bool type_is_global_error_set(ZigType *err_set_type); |
| 76 | void resolve_container_type(CodeGen *g, ZigType *type_entry); | 76 | Error resolve_container_type(CodeGen *g, ZigType *type_entry); |
| 77 | ScopeDecls *get_container_scope(ZigType *type_entry); | 77 | ScopeDecls *get_container_scope(ZigType *type_entry); |
| 78 | TypeStructField *find_struct_type_field(ZigType *type_entry, Buf *name); | 78 | TypeStructField *find_struct_type_field(ZigType *type_entry, Buf *name); |
| 79 | TypeEnumField *find_enum_type_field(ZigType *enum_type, Buf *name); | 79 | TypeEnumField *find_enum_type_field(ZigType *enum_type, Buf *name); |
| ... | @@ -246,4 +246,5 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose | ... | @@ -246,4 +246,5 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose |
| 246 | 246 | ||
| 247 | LLVMTypeRef get_llvm_type(CodeGen *g, ZigType *type); | 247 | LLVMTypeRef get_llvm_type(CodeGen *g, ZigType *type); |
| 248 | ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type); | 248 | ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type); |
| 249 | |||
| 249 | #endif | 250 | #endif |
src/codegen.cpp+13-5| ... | @@ -483,6 +483,8 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) { | ... | @@ -483,6 +483,8 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) { |
| 483 | 483 | ||
| 484 | 484 | ||
| 485 | ZigType *fn_type = fn_table_entry->type_entry; | 485 | ZigType *fn_type = fn_table_entry->type_entry; |
| 486 | // Make the raw_type_ref populated | ||
| 487 | (void)get_llvm_type(g, fn_type); | ||
| 486 | LLVMTypeRef fn_llvm_type = fn_type->data.fn.raw_type_ref; | 488 | LLVMTypeRef fn_llvm_type = fn_type->data.fn.raw_type_ref; |
| 487 | if (fn_table_entry->body_node == nullptr) { | 489 | if (fn_table_entry->body_node == nullptr) { |
| 488 | LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, buf_ptr(symbol_name)); | 490 | LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, buf_ptr(symbol_name)); |
| ... | @@ -2285,7 +2287,9 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) { | ... | @@ -2285,7 +2287,9 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) { |
| 2285 | 2287 | ||
| 2286 | if (!handle_is_ptr(variable->var_type)) { | 2288 | if (!handle_is_ptr(variable->var_type)) { |
| 2287 | clear_debug_source_node(g); | 2289 | clear_debug_source_node(g); |
| 2288 | gen_store_untyped(g, LLVMGetParam(llvm_fn, (unsigned)variable->gen_arg_index), | 2290 | ZigType *fn_type = fn_table_entry->type_entry; |
| 2291 | unsigned gen_arg_index = fn_type->data.fn.gen_param_info[variable->src_arg_index].gen_index; | ||
| 2292 | gen_store_untyped(g, LLVMGetParam(llvm_fn, gen_arg_index), | ||
| 2289 | variable->value_ref, variable->align_bytes, false); | 2293 | variable->value_ref, variable->align_bytes, false); |
| 2290 | } | 2294 | } |
| 2291 | 2295 | ||
| ... | @@ -3354,6 +3358,8 @@ static bool value_is_all_undef_array(ConstExprValue *const_val, size_t len) { | ... | @@ -3354,6 +3358,8 @@ static bool value_is_all_undef_array(ConstExprValue *const_val, size_t len) { |
| 3354 | 3358 | ||
| 3355 | static bool value_is_all_undef(ConstExprValue *const_val) { | 3359 | static bool value_is_all_undef(ConstExprValue *const_val) { |
| 3356 | switch (const_val->special) { | 3360 | switch (const_val->special) { |
| 3361 | case ConstValSpecialLazy: | ||
| 3362 | zig_unreachable(); | ||
| 3357 | case ConstValSpecialRuntime: | 3363 | case ConstValSpecialRuntime: |
| 3358 | return false; | 3364 | return false; |
| 3359 | case ConstValSpecialUndef: | 3365 | case ConstValSpecialUndef: |
| ... | @@ -5818,6 +5824,7 @@ static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ConstExprValue *un | ... | @@ -5818,6 +5824,7 @@ static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ConstExprValue *un |
| 5818 | 5824 | ||
| 5819 | static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, ConstExprValue *const_val) { | 5825 | static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, ConstExprValue *const_val) { |
| 5820 | switch (const_val->special) { | 5826 | switch (const_val->special) { |
| 5827 | case ConstValSpecialLazy: | ||
| 5821 | case ConstValSpecialRuntime: | 5828 | case ConstValSpecialRuntime: |
| 5822 | zig_unreachable(); | 5829 | zig_unreachable(); |
| 5823 | case ConstValSpecialUndef: | 5830 | case ConstValSpecialUndef: |
| ... | @@ -6075,6 +6082,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c | ... | @@ -6075,6 +6082,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c |
| 6075 | assert(type_has_bits(type_entry)); | 6082 | assert(type_has_bits(type_entry)); |
| 6076 | 6083 | ||
| 6077 | switch (const_val->special) { | 6084 | switch (const_val->special) { |
| 6085 | case ConstValSpecialLazy: | ||
| 6078 | case ConstValSpecialRuntime: | 6086 | case ConstValSpecialRuntime: |
| 6079 | zig_unreachable(); | 6087 | zig_unreachable(); |
| 6080 | case ConstValSpecialUndef: | 6088 | case ConstValSpecialUndef: |
| ... | @@ -6834,9 +6842,9 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -6834,9 +6842,9 @@ static void do_code_gen(CodeGen *g) { |
| 6834 | fn_walk_var.data.vars.var = var; | 6842 | fn_walk_var.data.vars.var = var; |
| 6835 | iter_function_params_c_abi(g, fn_table_entry->type_entry, &fn_walk_var, var->src_arg_index); | 6843 | iter_function_params_c_abi(g, fn_table_entry->type_entry, &fn_walk_var, var->src_arg_index); |
| 6836 | } else { | 6844 | } else { |
| 6837 | assert(var->gen_arg_index != SIZE_MAX); | ||
| 6838 | ZigType *gen_type; | 6845 | ZigType *gen_type; |
| 6839 | FnGenParamInfo *gen_info = &fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index]; | 6846 | FnGenParamInfo *gen_info = &fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index]; |
| 6847 | assert(gen_info->gen_index != SIZE_MAX); | ||
| 6840 | 6848 | ||
| 6841 | if (handle_is_ptr(var->var_type)) { | 6849 | if (handle_is_ptr(var->var_type)) { |
| 6842 | if (gen_info->is_byval) { | 6850 | if (gen_info->is_byval) { |
| ... | @@ -6844,7 +6852,7 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -6844,7 +6852,7 @@ static void do_code_gen(CodeGen *g) { |
| 6844 | } else { | 6852 | } else { |
| 6845 | gen_type = gen_info->type; | 6853 | gen_type = gen_info->type; |
| 6846 | } | 6854 | } |
| 6847 | var->value_ref = LLVMGetParam(fn, (unsigned)var->gen_arg_index); | 6855 | var->value_ref = LLVMGetParam(fn, gen_info->gen_index); |
| 6848 | } else { | 6856 | } else { |
| 6849 | gen_type = var->var_type; | 6857 | gen_type = var->var_type; |
| 6850 | var->value_ref = build_alloca(g, var->var_type, buf_ptr(&var->name), var->align_bytes); | 6858 | var->value_ref = build_alloca(g, var->var_type, buf_ptr(&var->name), var->align_bytes); |
| ... | @@ -6853,7 +6861,7 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -6853,7 +6861,7 @@ static void do_code_gen(CodeGen *g) { |
| 6853 | var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope), | 6861 | var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope), |
| 6854 | buf_ptr(&var->name), import->data.structure.root_struct->di_file, | 6862 | buf_ptr(&var->name), import->data.structure.root_struct->di_file, |
| 6855 | (unsigned)(var->decl_node->line + 1), | 6863 | (unsigned)(var->decl_node->line + 1), |
| 6856 | get_llvm_di_type(g, gen_type), !g->strip_debug_symbols, 0, (unsigned)(var->gen_arg_index + 1)); | 6864 | get_llvm_di_type(g, gen_type), !g->strip_debug_symbols, 0, (unsigned)(gen_info->gen_index)); |
| 6857 | } | 6865 | } |
| 6858 | 6866 | ||
| 6859 | } | 6867 | } |
| ... | @@ -8241,7 +8249,7 @@ static void gen_root_source(CodeGen *g) { | ... | @@ -8241,7 +8249,7 @@ static void gen_root_source(CodeGen *g) { |
| 8241 | } | 8249 | } |
| 8242 | Tld *panic_tld = find_decl(g, &get_container_scope(import_with_panic)->base, buf_create_from_str("panic")); | 8250 | Tld *panic_tld = find_decl(g, &get_container_scope(import_with_panic)->base, buf_create_from_str("panic")); |
| 8243 | assert(panic_tld != nullptr); | 8251 | assert(panic_tld != nullptr); |
| 8244 | resolve_top_level_decl(g, panic_tld, nullptr); | 8252 | resolve_top_level_decl(g, panic_tld, nullptr, false); |
| 8245 | } | 8253 | } |
| 8246 | 8254 | ||
| 8247 | 8255 |
src/ir.cpp+335-143| ... | @@ -154,6 +154,7 @@ struct ConstCastBadAllowsZero { | ... | @@ -154,6 +154,7 @@ struct ConstCastBadAllowsZero { |
| 154 | enum UndefAllowed { | 154 | enum UndefAllowed { |
| 155 | UndefOk, | 155 | UndefOk, |
| 156 | UndefBad, | 156 | UndefBad, |
| 157 | LazyOk, | ||
| 157 | }; | 158 | }; |
| 158 | 159 | ||
| 159 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); | 160 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); |
| ... | @@ -10256,32 +10257,57 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio | ... | @@ -10256,32 +10257,57 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio |
| 10256 | return const_instr; | 10257 | return const_instr; |
| 10257 | } | 10258 | } |
| 10258 | 10259 | ||
| 10260 | static Error ir_resolve_const_val(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, | ||
| 10261 | ConstExprValue *val, UndefAllowed undef_allowed) | ||
| 10262 | { | ||
| 10263 | Error err; | ||
| 10264 | for (;;) { | ||
| 10265 | switch (val->special) { | ||
| 10266 | case ConstValSpecialStatic: | ||
| 10267 | return ErrorNone; | ||
| 10268 | case ConstValSpecialRuntime: | ||
| 10269 | if (!type_has_bits(val->type)) | ||
| 10270 | return ErrorNone; | ||
| 10271 | |||
| 10272 | exec_add_error_node(codegen, exec, source_node, | ||
| 10273 | buf_sprintf("unable to evaluate constant expression")); | ||
| 10274 | return ErrorSemanticAnalyzeFail; | ||
| 10275 | case ConstValSpecialUndef: | ||
| 10276 | if (undef_allowed == UndefOk) | ||
| 10277 | return ErrorNone; | ||
| 10278 | |||
| 10279 | exec_add_error_node(codegen, exec, source_node, | ||
| 10280 | buf_sprintf("use of undefined value here causes undefined behavior")); | ||
| 10281 | return ErrorSemanticAnalyzeFail; | ||
| 10282 | case ConstValSpecialLazy: | ||
| 10283 | if (undef_allowed == LazyOk) | ||
| 10284 | return ErrorNone; | ||
| 10285 | |||
| 10286 | if ((err = ir_resolve_lazy(codegen, source_node, val))) | ||
| 10287 | return err; | ||
| 10288 | |||
| 10289 | continue; | ||
| 10290 | } | ||
| 10291 | } | ||
| 10292 | } | ||
| 10293 | |||
| 10259 | static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) { | 10294 | static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) { |
| 10260 | switch (value->value.special) { | 10295 | Error err; |
| 10261 | case ConstValSpecialStatic: | 10296 | if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, value->source_node, |
| 10262 | return &value->value; | 10297 | &value->value, undef_allowed))) |
| 10263 | case ConstValSpecialRuntime: | 10298 | { |
| 10264 | if (!type_has_bits(value->value.type)) { | 10299 | return nullptr; |
| 10265 | return &value->value; | ||
| 10266 | } | ||
| 10267 | ir_add_error(ira, value, buf_sprintf("unable to evaluate constant expression")); | ||
| 10268 | return nullptr; | ||
| 10269 | case ConstValSpecialUndef: | ||
| 10270 | if (undef_allowed == UndefOk) { | ||
| 10271 | return &value->value; | ||
| 10272 | } else { | ||
| 10273 | ir_add_error(ira, value, buf_sprintf("use of undefined value here causes undefined behavior")); | ||
| 10274 | return nullptr; | ||
| 10275 | } | ||
| 10276 | } | 10300 | } |
| 10277 | zig_unreachable(); | 10301 | return &value->value; |
| 10278 | } | 10302 | } |
| 10279 | 10303 | ||
| 10280 | ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, | 10304 | ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, |
| 10281 | ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, | 10305 | ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, |
| 10282 | ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, | 10306 | ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, |
| 10283 | IrExecutable *parent_exec, AstNode *expected_type_source_node) | 10307 | IrExecutable *parent_exec, AstNode *expected_type_source_node, bool allow_lazy) |
| 10284 | { | 10308 | { |
| 10309 | Error err; | ||
| 10310 | |||
| 10285 | if (expected_type != nullptr && type_is_invalid(expected_type)) | 10311 | if (expected_type != nullptr && type_is_invalid(expected_type)) |
| 10286 | return &codegen->invalid_instruction->value; | 10312 | return &codegen->invalid_instruction->value; |
| 10287 | 10313 | ||
| ... | @@ -10326,7 +10352,24 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod | ... | @@ -10326,7 +10352,24 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod |
| 10326 | fprintf(stderr, "}\n"); | 10352 | fprintf(stderr, "}\n"); |
| 10327 | } | 10353 | } |
| 10328 | 10354 | ||
| 10329 | return ir_exec_const_result(codegen, analyzed_executable); | 10355 | ConstExprValue *result = ir_exec_const_result(codegen, analyzed_executable); |
| 10356 | |||
| 10357 | if (!allow_lazy) { | ||
| 10358 | if ((err = ir_resolve_lazy(codegen, node, result))) | ||
| 10359 | return &codegen->invalid_instruction->value; | ||
| 10360 | } | ||
| 10361 | return result; | ||
| 10362 | } | ||
| 10363 | |||
| 10364 | static ZigType *ir_resolve_const_type(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, | ||
| 10365 | ConstExprValue *val) | ||
| 10366 | { | ||
| 10367 | Error err; | ||
| 10368 | if ((err = ir_resolve_const_val(codegen, exec, source_node, val, UndefBad))) | ||
| 10369 | return codegen->builtin_types.entry_invalid; | ||
| 10370 | |||
| 10371 | assert(val->data.x_type != nullptr); | ||
| 10372 | return val->data.x_type; | ||
| 10330 | } | 10373 | } |
| 10331 | 10374 | ||
| 10332 | static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { | 10375 | static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { |
| ... | @@ -10339,12 +10382,7 @@ static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { | ... | @@ -10339,12 +10382,7 @@ static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { |
| 10339 | return ira->codegen->builtin_types.entry_invalid; | 10382 | return ira->codegen->builtin_types.entry_invalid; |
| 10340 | } | 10383 | } |
| 10341 | 10384 | ||
| 10342 | ConstExprValue *const_val = ir_resolve_const(ira, type_value, UndefBad); | 10385 | return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, type_value->source_node, &type_value->value); |
| 10343 | if (!const_val) | ||
| 10344 | return ira->codegen->builtin_types.entry_invalid; | ||
| 10345 | |||
| 10346 | assert(const_val->data.x_type != nullptr); | ||
| 10347 | return const_val->data.x_type; | ||
| 10348 | } | 10386 | } |
| 10349 | 10387 | ||
| 10350 | static ZigType *ir_resolve_error_set_type(IrAnalyze *ira, IrInstruction *op_source, IrInstruction *type_value) { | 10388 | static ZigType *ir_resolve_error_set_type(IrAnalyze *ira, IrInstruction *op_source, IrInstruction *type_value) { |
| ... | @@ -11835,33 +11873,38 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc | ... | @@ -11835,33 +11873,38 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc |
| 11835 | } | 11873 | } |
| 11836 | } | 11874 | } |
| 11837 | 11875 | ||
| 11838 | static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) { | 11876 | static bool ir_resolve_const_align(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, |
| 11839 | if (type_is_invalid(value->value.type)) | 11877 | ConstExprValue *const_val, uint32_t *out) |
| 11840 | return false; | 11878 | { |
| 11841 | 11879 | Error err; | |
| 11842 | IrInstruction *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); | 11880 | if ((err = ir_resolve_const_val(codegen, exec, source_node, const_val, UndefBad))) |
| 11843 | if (type_is_invalid(casted_value->value.type)) | ||
| 11844 | return false; | ||
| 11845 | |||
| 11846 | ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); | ||
| 11847 | if (!const_val) | ||
| 11848 | return false; | 11881 | return false; |
| 11849 | 11882 | ||
| 11850 | uint32_t align_bytes = bigint_as_unsigned(&const_val->data.x_bigint); | 11883 | uint32_t align_bytes = bigint_as_unsigned(&const_val->data.x_bigint); |
| 11851 | if (align_bytes == 0) { | 11884 | if (align_bytes == 0) { |
| 11852 | ir_add_error(ira, value, buf_sprintf("alignment must be >= 1")); | 11885 | exec_add_error_node(codegen, exec, source_node, buf_sprintf("alignment must be >= 1")); |
| 11853 | return false; | 11886 | return false; |
| 11854 | } | 11887 | } |
| 11855 | 11888 | ||
| 11856 | if (!is_power_of_2(align_bytes)) { | 11889 | if (!is_power_of_2(align_bytes)) { |
| 11857 | ir_add_error(ira, value, buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); | 11890 | exec_add_error_node(codegen, exec, source_node, buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); |
| 11858 | return false; | 11891 | return false; |
| 11859 | } | 11892 | } |
| 11860 | |||
| 11861 | *out = align_bytes; | 11893 | *out = align_bytes; |
| 11862 | return true; | 11894 | return true; |
| 11863 | } | 11895 | } |
| 11864 | 11896 | ||
| 11897 | static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) { | ||
| 11898 | if (type_is_invalid(value->value.type)) | ||
| 11899 | return false; | ||
| 11900 | |||
| 11901 | IrInstruction *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); | ||
| 11902 | if (type_is_invalid(casted_value->value.type)) | ||
| 11903 | return false; | ||
| 11904 | |||
| 11905 | return ir_resolve_const_align(ira->codegen, ira->new_irb.exec, value->source_node, &casted_value->value, out); | ||
| 11906 | } | ||
| 11907 | |||
| 11865 | static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstruction *value, ZigType *int_type, uint64_t *out) { | 11908 | static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstruction *value, ZigType *int_type, uint64_t *out) { |
| 11866 | if (type_is_invalid(value->value.type)) | 11909 | if (type_is_invalid(value->value.type)) |
| 11867 | return false; | 11910 | return false; |
| ... | @@ -12029,6 +12072,140 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { | ... | @@ -12029,6 +12072,140 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { |
| 12029 | return result; | 12072 | return result; |
| 12030 | } | 12073 | } |
| 12031 | 12074 | ||
| 12075 | static ZigType *ir_resolve_lazy_fn_type(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, | ||
| 12076 | LazyValueFnType *lazy_fn_type) | ||
| 12077 | { | ||
| 12078 | AstNode *proto_node = lazy_fn_type->proto_node; | ||
| 12079 | |||
| 12080 | FnTypeId fn_type_id = {0}; | ||
| 12081 | init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length); | ||
| 12082 | |||
| 12083 | for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { | ||
| 12084 | AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); | ||
| 12085 | assert(param_node->type == NodeTypeParamDecl); | ||
| 12086 | |||
| 12087 | bool param_is_var_args = param_node->data.param_decl.is_var_args; | ||
| 12088 | if (param_is_var_args) { | ||
| 12089 | if (fn_type_id.cc == CallingConventionC) { | ||
| 12090 | fn_type_id.param_count = fn_type_id.next_param_index; | ||
| 12091 | continue; | ||
| 12092 | } else if (fn_type_id.cc == CallingConventionUnspecified) { | ||
| 12093 | return get_generic_fn_type(codegen, &fn_type_id); | ||
| 12094 | } else { | ||
| 12095 | zig_unreachable(); | ||
| 12096 | } | ||
| 12097 | } | ||
| 12098 | FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; | ||
| 12099 | param_info->is_noalias = param_node->data.param_decl.is_noalias; | ||
| 12100 | |||
| 12101 | if (lazy_fn_type->param_types[fn_type_id.next_param_index] == nullptr) { | ||
| 12102 | param_info->type = nullptr; | ||
| 12103 | return get_generic_fn_type(codegen, &fn_type_id); | ||
| 12104 | } else { | ||
| 12105 | ZigType *param_type = ir_resolve_const_type(codegen, exec, source_node, | ||
| 12106 | lazy_fn_type->param_types[fn_type_id.next_param_index]); | ||
| 12107 | if (type_is_invalid(param_type)) | ||
| 12108 | return nullptr; | ||
| 12109 | switch (type_requires_comptime(codegen, param_type)) { | ||
| 12110 | case ReqCompTimeYes: | ||
| 12111 | if (!calling_convention_allows_zig_types(fn_type_id.cc)) { | ||
| 12112 | exec_add_error_node(codegen, exec, source_node, | ||
| 12113 | buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", | ||
| 12114 | buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc))); | ||
| 12115 | return nullptr; | ||
| 12116 | } | ||
| 12117 | param_info->type = param_type; | ||
| 12118 | fn_type_id.next_param_index += 1; | ||
| 12119 | return get_generic_fn_type(codegen, &fn_type_id); | ||
| 12120 | case ReqCompTimeInvalid: | ||
| 12121 | return nullptr; | ||
| 12122 | case ReqCompTimeNo: | ||
| 12123 | break; | ||
| 12124 | } | ||
| 12125 | if (!type_has_bits(param_type) && !calling_convention_allows_zig_types(fn_type_id.cc)) { | ||
| 12126 | exec_add_error_node(codegen, exec, source_node, | ||
| 12127 | buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", | ||
| 12128 | buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc))); | ||
| 12129 | return nullptr; | ||
| 12130 | } | ||
| 12131 | param_info->type = param_type; | ||
| 12132 | } | ||
| 12133 | |||
| 12134 | } | ||
| 12135 | |||
| 12136 | if (lazy_fn_type->align_val != nullptr) { | ||
| 12137 | if (!ir_resolve_const_align(codegen, exec, source_node, lazy_fn_type->align_val, &fn_type_id.alignment)) | ||
| 12138 | return nullptr; | ||
| 12139 | } | ||
| 12140 | |||
| 12141 | fn_type_id.return_type = ir_resolve_const_type(codegen, exec, source_node, lazy_fn_type->return_type); | ||
| 12142 | if (type_is_invalid(fn_type_id.return_type)) | ||
| 12143 | return nullptr; | ||
| 12144 | if (fn_type_id.return_type->id == ZigTypeIdOpaque) { | ||
| 12145 | exec_add_error_node(codegen, exec, source_node, | ||
| 12146 | buf_sprintf("return type cannot be opaque")); | ||
| 12147 | return nullptr; | ||
| 12148 | } | ||
| 12149 | |||
| 12150 | if (lazy_fn_type->async_allocator_type != nullptr) { | ||
| 12151 | fn_type_id.async_allocator_type = ir_resolve_const_type(codegen, exec, source_node, | ||
| 12152 | lazy_fn_type->async_allocator_type); | ||
| 12153 | if (type_is_invalid(fn_type_id.async_allocator_type)) | ||
| 12154 | return nullptr; | ||
| 12155 | } | ||
| 12156 | |||
| 12157 | return get_fn_type(codegen, &fn_type_id); | ||
| 12158 | } | ||
| 12159 | |||
| 12160 | Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ConstExprValue *val) { | ||
| 12161 | Error err; | ||
| 12162 | if (val->special != ConstValSpecialLazy) | ||
| 12163 | return ErrorNone; | ||
| 12164 | IrExecutable *exec = val->data.x_lazy->exec; | ||
| 12165 | switch (val->data.x_lazy->id) { | ||
| 12166 | case LazyValueIdInvalid: | ||
| 12167 | zig_unreachable(); | ||
| 12168 | case LazyValueIdAlignOf: { | ||
| 12169 | LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy); | ||
| 12170 | if ((err = type_resolve(codegen, lazy_align_of->target_type, ResolveStatusAlignmentKnown))) | ||
| 12171 | return err; | ||
| 12172 | uint64_t align_in_bytes = get_abi_alignment(codegen, lazy_align_of->target_type); | ||
| 12173 | val->special = ConstValSpecialStatic; | ||
| 12174 | assert(val->type->id == ZigTypeIdComptimeInt); | ||
| 12175 | bigint_init_unsigned(&val->data.x_bigint, align_in_bytes); | ||
| 12176 | return ErrorNone; | ||
| 12177 | } | ||
| 12178 | case LazyValueIdSliceType: { | ||
| 12179 | LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(val->data.x_lazy); | ||
| 12180 | uint32_t align_bytes = 0; | ||
| 12181 | if (lazy_slice_type->align_val != nullptr) { | ||
| 12182 | if (!ir_resolve_const_align(codegen, exec, source_node, lazy_slice_type->align_val, &align_bytes)) | ||
| 12183 | return ErrorSemanticAnalyzeFail; | ||
| 12184 | } | ||
| 12185 | if ((err = type_resolve(codegen, lazy_slice_type->elem_type, ResolveStatusZeroBitsKnown))) | ||
| 12186 | return err; | ||
| 12187 | ZigType *slice_ptr_type = get_pointer_to_type_extra(codegen, lazy_slice_type->elem_type, | ||
| 12188 | lazy_slice_type->is_const, lazy_slice_type->is_volatile, PtrLenUnknown, align_bytes, | ||
| 12189 | 0, 0, lazy_slice_type->is_allowzero); | ||
| 12190 | val->special = ConstValSpecialStatic; | ||
| 12191 | assert(val->type->id == ZigTypeIdMetaType); | ||
| 12192 | val->data.x_type = get_slice_type(codegen, slice_ptr_type); | ||
| 12193 | return ErrorNone; | ||
| 12194 | } | ||
| 12195 | case LazyValueIdFnType: { | ||
| 12196 | ZigType *fn_type = ir_resolve_lazy_fn_type(codegen, exec, source_node, | ||
| 12197 | reinterpret_cast<LazyValueFnType *>(val->data.x_lazy)); | ||
| 12198 | if (fn_type == nullptr) | ||
| 12199 | return ErrorSemanticAnalyzeFail; | ||
| 12200 | val->special = ConstValSpecialStatic; | ||
| 12201 | assert(val->type->id == ZigTypeIdMetaType); | ||
| 12202 | val->data.x_type = fn_type; | ||
| 12203 | return ErrorNone; | ||
| 12204 | } | ||
| 12205 | } | ||
| 12206 | zig_unreachable(); | ||
| 12207 | } | ||
| 12208 | |||
| 12032 | static IrInstruction *ir_analyze_instruction_add_implicit_return_type(IrAnalyze *ira, | 12209 | static IrInstruction *ir_analyze_instruction_add_implicit_return_type(IrAnalyze *ira, |
| 12033 | IrInstructionAddImplicitReturnType *instruction) | 12210 | IrInstructionAddImplicitReturnType *instruction) |
| 12034 | { | 12211 | { |
| ... | @@ -13964,20 +14141,19 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod | ... | @@ -13964,20 +14141,19 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod |
| 13964 | } | 14141 | } |
| 13965 | 14142 | ||
| 13966 | static ZigVar *get_fn_var_by_index(ZigFn *fn_entry, size_t index) { | 14143 | static ZigVar *get_fn_var_by_index(ZigFn *fn_entry, size_t index) { |
| 14144 | FnTypeParamInfo *src_param_info = &fn_entry->type_entry->data.fn.fn_type_id.param_info[index]; | ||
| 14145 | if (!type_has_bits(src_param_info->type)) | ||
| 14146 | return nullptr; | ||
| 14147 | |||
| 13967 | size_t next_var_i = 0; | 14148 | size_t next_var_i = 0; |
| 13968 | FnGenParamInfo *gen_param_info = fn_entry->type_entry->data.fn.gen_param_info; | ||
| 13969 | assert(gen_param_info != nullptr); | ||
| 13970 | for (size_t param_i = 0; param_i < index; param_i += 1) { | 14149 | for (size_t param_i = 0; param_i < index; param_i += 1) { |
| 13971 | FnGenParamInfo *info = &gen_param_info[param_i]; | 14150 | FnTypeParamInfo *src_param_info = &fn_entry->type_entry->data.fn.fn_type_id.param_info[param_i]; |
| 13972 | if (info->gen_index == SIZE_MAX) | 14151 | if (!type_has_bits(src_param_info->type)) { |
| 13973 | continue; | 14152 | continue; |
| 14153 | } | ||
| 13974 | 14154 | ||
| 13975 | next_var_i += 1; | 14155 | next_var_i += 1; |
| 13976 | } | 14156 | } |
| 13977 | FnGenParamInfo *info = &gen_param_info[index]; | ||
| 13978 | if (info->gen_index == SIZE_MAX) | ||
| 13979 | return nullptr; | ||
| 13980 | |||
| 13981 | return fn_entry->variable_list.at(next_var_i); | 14157 | return fn_entry->variable_list.at(next_var_i); |
| 13982 | } | 14158 | } |
| 13983 | 14159 | ||
| ... | @@ -14003,7 +14179,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, | ... | @@ -14003,7 +14179,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 14003 | if (linkage_makes_it_runtime) | 14179 | if (linkage_makes_it_runtime) |
| 14004 | goto no_mem_slot; | 14180 | goto no_mem_slot; |
| 14005 | 14181 | ||
| 14006 | if (var->const_value->special == ConstValSpecialStatic) { | 14182 | if (value_is_comptime(var->const_value)) { |
| 14007 | mem_slot = var->const_value; | 14183 | mem_slot = var->const_value; |
| 14008 | } else { | 14184 | } else { |
| 14009 | if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) { | 14185 | if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) { |
| ... | @@ -14021,6 +14197,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, | ... | @@ -14021,6 +14197,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 14021 | case ConstValSpecialRuntime: | 14197 | case ConstValSpecialRuntime: |
| 14022 | goto no_mem_slot; | 14198 | goto no_mem_slot; |
| 14023 | case ConstValSpecialStatic: // fallthrough | 14199 | case ConstValSpecialStatic: // fallthrough |
| 14200 | case ConstValSpecialLazy: // fallthrough | ||
| 14024 | case ConstValSpecialUndef: { | 14201 | case ConstValSpecialUndef: { |
| 14025 | ConstPtrMut ptr_mut; | 14202 | ConstPtrMut ptr_mut; |
| 14026 | if (comptime_var_mem) { | 14203 | if (comptime_var_mem) { |
| ... | @@ -14301,7 +14478,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -14301,7 +14478,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14301 | AstNode *body_node = fn_entry->body_node; | 14478 | AstNode *body_node = fn_entry->body_node; |
| 14302 | result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, | 14479 | result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, |
| 14303 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, | 14480 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, |
| 14304 | nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node); | 14481 | nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node, false); |
| 14305 | 14482 | ||
| 14306 | if (inferred_err_set_type != nullptr) { | 14483 | if (inferred_err_set_type != nullptr) { |
| 14307 | inferred_err_set_type->data.error_set.infer_fn = nullptr; | 14484 | inferred_err_set_type->data.error_set.infer_fn = nullptr; |
| ... | @@ -14497,7 +14674,8 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -14497,7 +14674,8 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14497 | ConstExprValue *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope, | 14674 | ConstExprValue *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope, |
| 14498 | fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen), | 14675 | fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen), |
| 14499 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, | 14676 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, |
| 14500 | nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr); | 14677 | nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr, |
| 14678 | false); | ||
| 14501 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, | 14679 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, |
| 14502 | impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); | 14680 | impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); |
| 14503 | const_instruction->base.value = *align_result; | 14681 | const_instruction->base.value = *align_result; |
| ... | @@ -15630,7 +15808,7 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, | ... | @@ -15630,7 +15808,7 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, |
| 15630 | auto entry = container_scope->decl_table.maybe_get(field_name); | 15808 | auto entry = container_scope->decl_table.maybe_get(field_name); |
| 15631 | Tld *tld = entry ? entry->value : nullptr; | 15809 | Tld *tld = entry ? entry->value : nullptr; |
| 15632 | if (tld && tld->id == TldIdFn) { | 15810 | if (tld && tld->id == TldIdFn) { |
| 15633 | resolve_top_level_decl(ira->codegen, tld, source_instr->source_node); | 15811 | resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false); |
| 15634 | if (tld->resolution == TldResolutionInvalid) | 15812 | if (tld->resolution == TldResolutionInvalid) |
| 15635 | return ira->codegen->invalid_instruction; | 15813 | return ira->codegen->invalid_instruction; |
| 15636 | TldFn *tld_fn = (TldFn *)tld; | 15814 | TldFn *tld_fn = (TldFn *)tld; |
| ... | @@ -15821,7 +15999,7 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, | ... | @@ -15821,7 +15999,7 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, |
| 15821 | 15999 | ||
| 15822 | 16000 | ||
| 15823 | static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) { | 16001 | static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) { |
| 15824 | resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node); | 16002 | resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node, false); |
| 15825 | if (tld->resolution == TldResolutionInvalid) | 16003 | if (tld->resolution == TldResolutionInvalid) |
| 15826 | return ira->codegen->invalid_instruction; | 16004 | return ira->codegen->invalid_instruction; |
| 15827 | 16005 | ||
| ... | @@ -16477,22 +16655,29 @@ static IrInstruction *ir_analyze_instruction_set_float_mode(IrAnalyze *ira, | ... | @@ -16477,22 +16655,29 @@ static IrInstruction *ir_analyze_instruction_set_float_mode(IrAnalyze *ira, |
| 16477 | static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, | 16655 | static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 16478 | IrInstructionSliceType *slice_type_instruction) | 16656 | IrInstructionSliceType *slice_type_instruction) |
| 16479 | { | 16657 | { |
| 16480 | Error err; | 16658 | IrInstruction *result = ir_const(ira, &slice_type_instruction->base, ira->codegen->builtin_types.entry_type); |
| 16481 | uint32_t align_bytes = 0; | 16659 | result->value.special = ConstValSpecialLazy; |
| 16660 | |||
| 16661 | LazyValueSliceType *lazy_slice_type = allocate<LazyValueSliceType>(1); | ||
| 16662 | result->value.data.x_lazy = &lazy_slice_type->base; | ||
| 16663 | lazy_slice_type->base.id = LazyValueIdSliceType; | ||
| 16664 | lazy_slice_type->base.exec = ira->new_irb.exec; | ||
| 16665 | |||
| 16482 | if (slice_type_instruction->align_value != nullptr) { | 16666 | if (slice_type_instruction->align_value != nullptr) { |
| 16483 | if (!ir_resolve_align(ira, slice_type_instruction->align_value->child, &align_bytes)) | 16667 | lazy_slice_type->align_val = ir_resolve_const(ira, slice_type_instruction->align_value->child, LazyOk); |
| 16668 | if (lazy_slice_type->align_val == nullptr) | ||
| 16484 | return ira->codegen->invalid_instruction; | 16669 | return ira->codegen->invalid_instruction; |
| 16485 | } | 16670 | } |
| 16486 | 16671 | ||
| 16487 | ZigType *child_type = ir_resolve_type(ira, slice_type_instruction->child_type->child); | 16672 | lazy_slice_type->elem_type = ir_resolve_type(ira, slice_type_instruction->child_type->child); |
| 16488 | if (type_is_invalid(child_type)) | 16673 | if (type_is_invalid(lazy_slice_type->elem_type)) |
| 16489 | return ira->codegen->invalid_instruction; | 16674 | return ira->codegen->invalid_instruction; |
| 16490 | 16675 | ||
| 16491 | bool is_const = slice_type_instruction->is_const; | 16676 | lazy_slice_type->is_const = slice_type_instruction->is_const; |
| 16492 | bool is_volatile = slice_type_instruction->is_volatile; | 16677 | lazy_slice_type->is_volatile = slice_type_instruction->is_volatile; |
| 16493 | bool is_allow_zero = slice_type_instruction->is_allow_zero; | 16678 | lazy_slice_type->is_allowzero = slice_type_instruction->is_allow_zero; |
| 16494 | 16679 | ||
| 16495 | switch (child_type->id) { | 16680 | switch (lazy_slice_type->elem_type->id) { |
| 16496 | case ZigTypeIdInvalid: // handled above | 16681 | case ZigTypeIdInvalid: // handled above |
| 16497 | zig_unreachable(); | 16682 | zig_unreachable(); |
| 16498 | case ZigTypeIdUnreachable: | 16683 | case ZigTypeIdUnreachable: |
| ... | @@ -16501,7 +16686,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, | ... | @@ -16501,7 +16686,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 16501 | case ZigTypeIdArgTuple: | 16686 | case ZigTypeIdArgTuple: |
| 16502 | case ZigTypeIdOpaque: | 16687 | case ZigTypeIdOpaque: |
| 16503 | ir_add_error_node(ira, slice_type_instruction->base.source_node, | 16688 | ir_add_error_node(ira, slice_type_instruction->base.source_node, |
| 16504 | buf_sprintf("slice of type '%s' not allowed", buf_ptr(&child_type->name))); | 16689 | buf_sprintf("slice of type '%s' not allowed", buf_ptr(&lazy_slice_type->elem_type->name))); |
| 16505 | return ira->codegen->invalid_instruction; | 16690 | return ira->codegen->invalid_instruction; |
| 16506 | case ZigTypeIdMetaType: | 16691 | case ZigTypeIdMetaType: |
| 16507 | case ZigTypeIdVoid: | 16692 | case ZigTypeIdVoid: |
| ... | @@ -16523,14 +16708,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, | ... | @@ -16523,14 +16708,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 16523 | case ZigTypeIdBoundFn: | 16708 | case ZigTypeIdBoundFn: |
| 16524 | case ZigTypeIdPromise: | 16709 | case ZigTypeIdPromise: |
| 16525 | case ZigTypeIdVector: | 16710 | case ZigTypeIdVector: |
| 16526 | { | 16711 | return result; |
| 16527 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown))) | ||
| 16528 | return ira->codegen->invalid_instruction; | ||
| 16529 | ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, child_type, | ||
| 16530 | is_const, is_volatile, PtrLenUnknown, align_bytes, 0, 0, is_allow_zero); | ||
| 16531 | ZigType *result_type = get_slice_type(ira->codegen, slice_ptr_type); | ||
| 16532 | return ir_const_type(ira, &slice_type_instruction->base, result_type); | ||
| 16533 | } | ||
| 16534 | } | 16712 | } |
| 16535 | zig_unreachable(); | 16713 | zig_unreachable(); |
| 16536 | } | 16714 | } |
| ... | @@ -16637,7 +16815,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, | ... | @@ -16637,7 +16815,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, |
| 16637 | case ZigTypeIdPromise: | 16815 | case ZigTypeIdPromise: |
| 16638 | case ZigTypeIdVector: | 16816 | case ZigTypeIdVector: |
| 16639 | { | 16817 | { |
| 16640 | if ((err = ensure_complete_type(ira->codegen, child_type))) | 16818 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) |
| 16641 | return ira->codegen->invalid_instruction; | 16819 | return ira->codegen->invalid_instruction; |
| 16642 | ZigType *result_type = get_array_type(ira->codegen, child_type, size); | 16820 | ZigType *result_type = get_array_type(ira->codegen, child_type, size); |
| 16643 | return ir_const_type(ira, &array_type_instruction->base, result_type); | 16821 | return ir_const_type(ira, &array_type_instruction->base, result_type); |
| ... | @@ -17513,6 +17691,8 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc | ... | @@ -17513,6 +17691,8 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 17513 | static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, | 17691 | static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, |
| 17514 | IrInstructionContainerInitList *instruction) | 17692 | IrInstructionContainerInitList *instruction) |
| 17515 | { | 17693 | { |
| 17694 | Error err; | ||
| 17695 | |||
| 17516 | ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child); | 17696 | ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child); |
| 17517 | if (type_is_invalid(container_type)) | 17697 | if (type_is_invalid(container_type)) |
| 17518 | return ira->codegen->invalid_instruction; | 17698 | return ira->codegen->invalid_instruction; |
| ... | @@ -17541,6 +17721,10 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, | ... | @@ -17541,6 +17721,10 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, |
| 17541 | child_type = pointer_type->data.pointer.child_type; | 17721 | child_type = pointer_type->data.pointer.child_type; |
| 17542 | } | 17722 | } |
| 17543 | 17723 | ||
| 17724 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) { | ||
| 17725 | return ira->codegen->invalid_instruction; | ||
| 17726 | } | ||
| 17727 | |||
| 17544 | ZigType *fixed_size_array_type = get_array_type(ira->codegen, child_type, elem_count); | 17728 | ZigType *fixed_size_array_type = get_array_type(ira->codegen, child_type, elem_count); |
| 17545 | 17729 | ||
| 17546 | ConstExprValue const_val = {}; | 17730 | ConstExprValue const_val = {}; |
| ... | @@ -17923,10 +18107,11 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig | ... | @@ -17923,10 +18107,11 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig |
| 17923 | Error err; | 18107 | Error err; |
| 17924 | ConstExprValue *type_info_var = get_builtin_value(ira->codegen, "TypeInfo"); | 18108 | ConstExprValue *type_info_var = get_builtin_value(ira->codegen, "TypeInfo"); |
| 17925 | assert(type_info_var->type->id == ZigTypeIdMetaType); | 18109 | assert(type_info_var->type->id == ZigTypeIdMetaType); |
| 17926 | assertNoError(ensure_complete_type(ira->codegen, type_info_var->data.x_type)); | ||
| 17927 | |||
| 17928 | ZigType *type_info_type = type_info_var->data.x_type; | 18110 | ZigType *type_info_type = type_info_var->data.x_type; |
| 17929 | assert(type_info_type->id == ZigTypeIdUnion); | 18111 | assert(type_info_type->id == ZigTypeIdUnion); |
| 18112 | if ((err = type_resolve(ira->codegen, type_info_type, ResolveStatusSizeKnown))) { | ||
| 18113 | zig_unreachable(); | ||
| 18114 | } | ||
| 17930 | 18115 | ||
| 17931 | if (type_name == nullptr && root == nullptr) | 18116 | if (type_name == nullptr && root == nullptr) |
| 17932 | return type_info_type; | 18117 | return type_info_type; |
| ... | @@ -17960,7 +18145,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, | ... | @@ -17960,7 +18145,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, |
| 17960 | { | 18145 | { |
| 17961 | Error err; | 18146 | Error err; |
| 17962 | ZigType *type_info_definition_type = ir_type_info_get_type(ira, "Definition", nullptr); | 18147 | ZigType *type_info_definition_type = ir_type_info_get_type(ira, "Definition", nullptr); |
| 17963 | if ((err = ensure_complete_type(ira->codegen, type_info_definition_type))) | 18148 | if ((err = type_resolve(ira->codegen, type_info_definition_type, ResolveStatusSizeKnown))) |
| 17964 | return err; | 18149 | return err; |
| 17965 | 18150 | ||
| 17966 | ensure_field_index(type_info_definition_type, "name", 0); | 18151 | ensure_field_index(type_info_definition_type, "name", 0); |
| ... | @@ -17987,7 +18172,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, | ... | @@ -17987,7 +18172,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, |
| 17987 | while ((curr_entry = decl_it.next()) != nullptr) { | 18172 | while ((curr_entry = decl_it.next()) != nullptr) { |
| 17988 | // If the definition is unresolved, force it to be resolved again. | 18173 | // If the definition is unresolved, force it to be resolved again. |
| 17989 | if (curr_entry->value->resolution == TldResolutionUnresolved) { | 18174 | if (curr_entry->value->resolution == TldResolutionUnresolved) { |
| 17990 | resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node); | 18175 | resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node, false); |
| 17991 | if (curr_entry->value->resolution != TldResolutionOk) { | 18176 | if (curr_entry->value->resolution != TldResolutionOk) { |
| 17992 | return ErrorSemanticAnalyzeFail; | 18177 | return ErrorSemanticAnalyzeFail; |
| 17993 | } | 18178 | } |
| ... | @@ -18480,6 +18665,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr | ... | @@ -18480,6 +18665,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 18480 | ensure_field_index(result->type, "fields", 2); | 18665 | ensure_field_index(result->type, "fields", 2); |
| 18481 | 18666 | ||
| 18482 | ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); | 18667 | ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); |
| 18668 | if ((err = type_resolve(ira->codegen, type_info_enum_field_type, ResolveStatusSizeKnown))) { | ||
| 18669 | zig_unreachable(); | ||
| 18670 | } | ||
| 18483 | uint32_t enum_field_count = type_entry->data.enumeration.src_field_count; | 18671 | uint32_t enum_field_count = type_entry->data.enumeration.src_field_count; |
| 18484 | 18672 | ||
| 18485 | ConstExprValue *enum_field_array = create_const_vals(1); | 18673 | ConstExprValue *enum_field_array = create_const_vals(1); |
| ... | @@ -18523,6 +18711,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr | ... | @@ -18523,6 +18711,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 18523 | result->data.x_optional = nullptr; | 18711 | result->data.x_optional = nullptr; |
| 18524 | break; | 18712 | break; |
| 18525 | } | 18713 | } |
| 18714 | if ((err = type_resolve(ira->codegen, type_info_error_type, ResolveStatusSizeKnown))) { | ||
| 18715 | zig_unreachable(); | ||
| 18716 | } | ||
| 18526 | ConstExprValue *slice_val = create_const_vals(1); | 18717 | ConstExprValue *slice_val = create_const_vals(1); |
| 18527 | result->data.x_optional = slice_val; | 18718 | result->data.x_optional = slice_val; |
| 18528 | 18719 | ||
| ... | @@ -18619,6 +18810,8 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr | ... | @@ -18619,6 +18810,8 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 18619 | ensure_field_index(result->type, "fields", 2); | 18810 | ensure_field_index(result->type, "fields", 2); |
| 18620 | 18811 | ||
| 18621 | ZigType *type_info_union_field_type = ir_type_info_get_type(ira, "UnionField", nullptr); | 18812 | ZigType *type_info_union_field_type = ir_type_info_get_type(ira, "UnionField", nullptr); |
| 18813 | if ((err = type_resolve(ira->codegen, type_info_union_field_type, ResolveStatusSizeKnown))) | ||
| 18814 | zig_unreachable(); | ||
| 18622 | uint32_t union_field_count = type_entry->data.unionation.src_field_count; | 18815 | uint32_t union_field_count = type_entry->data.unionation.src_field_count; |
| 18623 | 18816 | ||
| 18624 | ConstExprValue *union_field_array = create_const_vals(1); | 18817 | ConstExprValue *union_field_array = create_const_vals(1); |
| ... | @@ -18696,6 +18889,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr | ... | @@ -18696,6 +18889,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 18696 | ensure_field_index(result->type, "fields", 1); | 18889 | ensure_field_index(result->type, "fields", 1); |
| 18697 | 18890 | ||
| 18698 | ZigType *type_info_struct_field_type = ir_type_info_get_type(ira, "StructField", nullptr); | 18891 | ZigType *type_info_struct_field_type = ir_type_info_get_type(ira, "StructField", nullptr); |
| 18892 | if ((err = type_resolve(ira->codegen, type_info_struct_field_type, ResolveStatusSizeKnown))) { | ||
| 18893 | zig_unreachable(); | ||
| 18894 | } | ||
| 18699 | uint32_t struct_field_count = type_entry->data.structure.src_field_count; | 18895 | uint32_t struct_field_count = type_entry->data.structure.src_field_count; |
| 18700 | 18896 | ||
| 18701 | ConstExprValue *struct_field_array = create_const_vals(1); | 18897 | ConstExprValue *struct_field_array = create_const_vals(1); |
| ... | @@ -18803,6 +18999,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr | ... | @@ -18803,6 +18999,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 18803 | } | 18999 | } |
| 18804 | // args: []TypeInfo.FnArg | 19000 | // args: []TypeInfo.FnArg |
| 18805 | ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); | 19001 | ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); |
| 19002 | if ((err = type_resolve(ira->codegen, type_info_fn_arg_type, ResolveStatusSizeKnown))) { | ||
| 19003 | zig_unreachable(); | ||
| 19004 | } | ||
| 18806 | size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count - | 19005 | size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count - |
| 18807 | (is_varargs && type_entry->data.fn.fn_type_id.cc != CallingConventionC); | 19006 | (is_varargs && type_entry->data.fn.fn_type_id.cc != CallingConventionC); |
| 18808 | 19007 | ||
| ... | @@ -18962,7 +19161,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct | ... | @@ -18962,7 +19161,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct |
| 18962 | ZigType *void_type = ira->codegen->builtin_types.entry_void; | 19161 | ZigType *void_type = ira->codegen->builtin_types.entry_void; |
| 18963 | ConstExprValue *cimport_result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, | 19162 | ConstExprValue *cimport_result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, |
| 18964 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, | 19163 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, |
| 18965 | &cimport_scope->buf, block_node, nullptr, nullptr, nullptr); | 19164 | &cimport_scope->buf, block_node, nullptr, nullptr, nullptr, false); |
| 18966 | if (type_is_invalid(cimport_result->type)) | 19165 | if (type_is_invalid(cimport_result->type)) |
| 18967 | return ira->codegen->invalid_instruction; | 19166 | return ira->codegen->invalid_instruction; |
| 18968 | 19167 | ||
| ... | @@ -20509,15 +20708,11 @@ static IrInstruction *ir_analyze_instruction_handle(IrAnalyze *ira, IrInstructio | ... | @@ -20509,15 +20708,11 @@ static IrInstruction *ir_analyze_instruction_handle(IrAnalyze *ira, IrInstructio |
| 20509 | } | 20708 | } |
| 20510 | 20709 | ||
| 20511 | static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) { | 20710 | static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) { |
| 20512 | Error err; | ||
| 20513 | IrInstruction *type_value = instruction->type_value->child; | 20711 | IrInstruction *type_value = instruction->type_value->child; |
| 20514 | if (type_is_invalid(type_value->value.type)) | 20712 | if (type_is_invalid(type_value->value.type)) |
| 20515 | return ira->codegen->invalid_instruction; | 20713 | return ira->codegen->invalid_instruction; |
| 20516 | ZigType *type_entry = ir_resolve_type(ira, type_value); | 20714 | ZigType *type_entry = ir_resolve_type(ira, type_value); |
| 20517 | 20715 | ||
| 20518 | if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusAlignmentKnown))) | ||
| 20519 | return ira->codegen->invalid_instruction; | ||
| 20520 | |||
| 20521 | switch (type_entry->id) { | 20716 | switch (type_entry->id) { |
| 20522 | case ZigTypeIdInvalid: | 20717 | case ZigTypeIdInvalid: |
| 20523 | zig_unreachable(); | 20718 | zig_unreachable(); |
| ... | @@ -20549,12 +20744,25 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct | ... | @@ -20549,12 +20744,25 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct |
| 20549 | case ZigTypeIdUnion: | 20744 | case ZigTypeIdUnion: |
| 20550 | case ZigTypeIdFn: | 20745 | case ZigTypeIdFn: |
| 20551 | case ZigTypeIdVector: | 20746 | case ZigTypeIdVector: |
| 20552 | { | 20747 | break; |
| 20553 | uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry); | ||
| 20554 | return ir_const_unsigned(ira, &instruction->base, align_in_bytes); | ||
| 20555 | } | ||
| 20556 | } | 20748 | } |
| 20557 | zig_unreachable(); | 20749 | if (type_is_resolved(type_entry, ResolveStatusAlignmentKnown)) { |
| 20750 | uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry); | ||
| 20751 | return ir_const_unsigned(ira, &instruction->base, align_in_bytes); | ||
| 20752 | } | ||
| 20753 | // Here we create a lazy value in order to avoid resolving the alignment of the type | ||
| 20754 | // immediately. This avoids false positive dependency loops such as: | ||
| 20755 | // const Node = struct { | ||
| 20756 | // field: []align(@alignOf(Node)) Node, | ||
| 20757 | // }; | ||
| 20758 | LazyValueAlignOf *lazy_align_of = allocate<LazyValueAlignOf>(1); | ||
| 20759 | lazy_align_of->base.id = LazyValueIdAlignOf; | ||
| 20760 | lazy_align_of->base.exec = ira->new_irb.exec; | ||
| 20761 | lazy_align_of->target_type = type_entry; | ||
| 20762 | IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); | ||
| 20763 | result->value.special = ConstValSpecialLazy; | ||
| 20764 | result->value.data.x_lazy = &lazy_align_of->base; | ||
| 20765 | return result; | ||
| 20558 | } | 20766 | } |
| 20559 | 20767 | ||
| 20560 | static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) { | 20768 | static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) { |
| ... | @@ -20809,96 +21017,77 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct | ... | @@ -20809,96 +21017,77 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct |
| 20809 | AstNode *proto_node = instruction->base.source_node; | 21017 | AstNode *proto_node = instruction->base.source_node; |
| 20810 | assert(proto_node->type == NodeTypeFnProto); | 21018 | assert(proto_node->type == NodeTypeFnProto); |
| 20811 | 21019 | ||
| 21020 | IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type); | ||
| 21021 | result->value.special = ConstValSpecialLazy; | ||
| 21022 | |||
| 21023 | LazyValueFnType *lazy_fn_type = allocate<LazyValueFnType>(1); | ||
| 21024 | result->value.data.x_lazy = &lazy_fn_type->base; | ||
| 21025 | lazy_fn_type->base.id = LazyValueIdFnType; | ||
| 21026 | lazy_fn_type->base.exec = ira->new_irb.exec; | ||
| 21027 | |||
| 20812 | if (proto_node->data.fn_proto.auto_err_set) { | 21028 | if (proto_node->data.fn_proto.auto_err_set) { |
| 20813 | ir_add_error(ira, &instruction->base, | 21029 | ir_add_error(ira, &instruction->base, |
| 20814 | buf_sprintf("inferring error set of return type valid only for function definitions")); | 21030 | buf_sprintf("inferring error set of return type valid only for function definitions")); |
| 20815 | return ira->codegen->invalid_instruction; | 21031 | return ira->codegen->invalid_instruction; |
| 20816 | } | 21032 | } |
| 20817 | 21033 | ||
| 20818 | FnTypeId fn_type_id = {0}; | 21034 | size_t param_count = proto_node->data.fn_proto.params.length; |
| 20819 | init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length); | 21035 | lazy_fn_type->proto_node = proto_node; |
| 21036 | lazy_fn_type->param_types = allocate<ConstExprValue *>(param_count); | ||
| 20820 | 21037 | ||
| 20821 | for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { | 21038 | for (size_t i = 0; i < param_count; i += 1) { |
| 20822 | AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); | 21039 | AstNode *param_node = proto_node->data.fn_proto.params.at(i); |
| 20823 | assert(param_node->type == NodeTypeParamDecl); | 21040 | assert(param_node->type == NodeTypeParamDecl); |
| 20824 | 21041 | ||
| 20825 | bool param_is_var_args = param_node->data.param_decl.is_var_args; | 21042 | bool param_is_var_args = param_node->data.param_decl.is_var_args; |
| 21043 | lazy_fn_type->is_var_args = true; | ||
| 20826 | if (param_is_var_args) { | 21044 | if (param_is_var_args) { |
| 20827 | if (fn_type_id.cc == CallingConventionC) { | 21045 | if (proto_node->data.fn_proto.cc == CallingConventionC) { |
| 20828 | fn_type_id.param_count = fn_type_id.next_param_index; | 21046 | break; |
| 20829 | continue; | 21047 | } else if (proto_node->data.fn_proto.cc == CallingConventionUnspecified) { |
| 20830 | } else if (fn_type_id.cc == CallingConventionUnspecified) { | 21048 | lazy_fn_type->is_generic = true; |
| 20831 | return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); | 21049 | return result; |
| 20832 | } else { | 21050 | } else { |
| 20833 | zig_unreachable(); | 21051 | zig_unreachable(); |
| 20834 | } | 21052 | } |
| 20835 | } | 21053 | } |
| 20836 | FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; | ||
| 20837 | param_info->is_noalias = param_node->data.param_decl.is_noalias; | ||
| 20838 | 21054 | ||
| 20839 | if (instruction->param_types[fn_type_id.next_param_index] == nullptr) { | 21055 | if (instruction->param_types[i] == nullptr) { |
| 20840 | param_info->type = nullptr; | 21056 | lazy_fn_type->is_generic = true; |
| 20841 | return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); | 21057 | return result; |
| 20842 | } else { | ||
| 20843 | IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->child; | ||
| 20844 | if (type_is_invalid(param_type_value->value.type)) | ||
| 20845 | return ira->codegen->invalid_instruction; | ||
| 20846 | ZigType *param_type = ir_resolve_type(ira, param_type_value); | ||
| 20847 | switch (type_requires_comptime(ira->codegen, param_type)) { | ||
| 20848 | case ReqCompTimeYes: | ||
| 20849 | if (!calling_convention_allows_zig_types(fn_type_id.cc)) { | ||
| 20850 | ir_add_error(ira, param_type_value, | ||
| 20851 | buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", | ||
| 20852 | buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc))); | ||
| 20853 | return ira->codegen->invalid_instruction; | ||
| 20854 | } | ||
| 20855 | param_info->type = param_type; | ||
| 20856 | fn_type_id.next_param_index += 1; | ||
| 20857 | return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); | ||
| 20858 | case ReqCompTimeInvalid: | ||
| 20859 | return ira->codegen->invalid_instruction; | ||
| 20860 | case ReqCompTimeNo: | ||
| 20861 | break; | ||
| 20862 | } | ||
| 20863 | if (!type_has_bits(param_type) && !calling_convention_allows_zig_types(fn_type_id.cc)) { | ||
| 20864 | ir_add_error(ira, param_type_value, | ||
| 20865 | buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", | ||
| 20866 | buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc))); | ||
| 20867 | return ira->codegen->invalid_instruction; | ||
| 20868 | } | ||
| 20869 | param_info->type = param_type; | ||
| 20870 | } | 21058 | } |
| 20871 | 21059 | ||
| 21060 | IrInstruction *param_type_value = instruction->param_types[i]->child; | ||
| 21061 | if (type_is_invalid(param_type_value->value.type)) | ||
| 21062 | return ira->codegen->invalid_instruction; | ||
| 21063 | ConstExprValue *param_type_val = ir_resolve_const(ira, param_type_value, LazyOk); | ||
| 21064 | if (param_type_val == nullptr) | ||
| 21065 | return ira->codegen->invalid_instruction; | ||
| 21066 | lazy_fn_type->param_types[i] = param_type_val; | ||
| 20872 | } | 21067 | } |
| 20873 | 21068 | ||
| 20874 | if (instruction->align_value != nullptr) { | 21069 | if (instruction->align_value != nullptr) { |
| 20875 | if (!ir_resolve_align(ira, instruction->align_value->child, &fn_type_id.alignment)) | 21070 | lazy_fn_type->align_val = ir_resolve_const(ira, instruction->align_value->child, LazyOk); |
| 21071 | if (lazy_fn_type->align_val == nullptr) | ||
| 20876 | return ira->codegen->invalid_instruction; | 21072 | return ira->codegen->invalid_instruction; |
| 20877 | } | 21073 | } |
| 20878 | 21074 | ||
| 20879 | IrInstruction *return_type_value = instruction->return_type->child; | 21075 | lazy_fn_type->return_type = ir_resolve_const(ira, instruction->return_type->child, LazyOk); |
| 20880 | fn_type_id.return_type = ir_resolve_type(ira, return_type_value); | 21076 | if (lazy_fn_type->return_type == nullptr) |
| 20881 | if (type_is_invalid(fn_type_id.return_type)) | ||
| 20882 | return ira->codegen->invalid_instruction; | ||
| 20883 | if (fn_type_id.return_type->id == ZigTypeIdOpaque) { | ||
| 20884 | ir_add_error(ira, instruction->return_type, | ||
| 20885 | buf_sprintf("return type cannot be opaque")); | ||
| 20886 | return ira->codegen->invalid_instruction; | 21077 | return ira->codegen->invalid_instruction; |
| 20887 | } | ||
| 20888 | 21078 | ||
| 20889 | if (fn_type_id.cc == CallingConventionAsync) { | 21079 | if (proto_node->data.fn_proto.cc == CallingConventionAsync) { |
| 20890 | if (instruction->async_allocator_type_value == nullptr) { | 21080 | if (instruction->async_allocator_type_value == nullptr) { |
| 20891 | ir_add_error(ira, &instruction->base, | 21081 | ir_add_error(ira, &instruction->base, |
| 20892 | buf_sprintf("async fn proto missing allocator type")); | 21082 | buf_sprintf("async fn proto missing allocator type")); |
| 20893 | return ira->codegen->invalid_instruction; | 21083 | return ira->codegen->invalid_instruction; |
| 20894 | } | 21084 | } |
| 20895 | IrInstruction *async_allocator_type_value = instruction->async_allocator_type_value->child; | 21085 | lazy_fn_type->async_allocator_type = ir_resolve_const(ira, instruction->async_allocator_type_value->child, LazyOk); |
| 20896 | fn_type_id.async_allocator_type = ir_resolve_type(ira, async_allocator_type_value); | 21086 | if (lazy_fn_type->async_allocator_type == nullptr) |
| 20897 | if (type_is_invalid(fn_type_id.async_allocator_type)) | ||
| 20898 | return ira->codegen->invalid_instruction; | 21087 | return ira->codegen->invalid_instruction; |
| 20899 | } | 21088 | } |
| 20900 | 21089 | ||
| 20901 | return ir_const_type(ira, &instruction->base, get_fn_type(ira->codegen, &fn_type_id)); | 21090 | return result; |
| 20902 | } | 21091 | } |
| 20903 | 21092 | ||
| 20904 | static IrInstruction *ir_analyze_instruction_test_comptime(IrAnalyze *ira, IrInstructionTestComptime *instruction) { | 21093 | static IrInstruction *ir_analyze_instruction_test_comptime(IrAnalyze *ira, IrInstructionTestComptime *instruction) { |
| ... | @@ -21567,8 +21756,11 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou | ... | @@ -21567,8 +21756,11 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou |
| 21567 | val->type->data.vector.len); | 21756 | val->type->data.vector.len); |
| 21568 | case ZigTypeIdEnum: | 21757 | case ZigTypeIdEnum: |
| 21569 | switch (val->type->data.enumeration.layout) { | 21758 | switch (val->type->data.enumeration.layout) { |
| 21570 | case ContainerLayoutAuto: | 21759 | case ContainerLayoutAuto: { |
| 21571 | zig_panic("TODO buf_read_value_bytes enum auto"); | 21760 | opt_ir_add_error_node(ira, codegen, source_node, |
| 21761 | buf_sprintf("compiler bug: TODO: implement enum byte reinterpretation")); | ||
| 21762 | return ErrorSemanticAnalyzeFail; | ||
| 21763 | } | ||
| 21572 | case ContainerLayoutPacked: | 21764 | case ContainerLayoutPacked: |
| 21573 | zig_panic("TODO buf_read_value_bytes enum packed"); | 21765 | zig_panic("TODO buf_read_value_bytes enum packed"); |
| 21574 | case ContainerLayoutExtern: { | 21766 | case ContainerLayoutExtern: { |
| ... | @@ -21864,7 +22056,7 @@ static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira, | ... | @@ -21864,7 +22056,7 @@ static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira, |
| 21864 | Tld *tld = instruction->tld; | 22056 | Tld *tld = instruction->tld; |
| 21865 | LVal lval = instruction->lval; | 22057 | LVal lval = instruction->lval; |
| 21866 | 22058 | ||
| 21867 | resolve_top_level_decl(ira->codegen, tld, instruction->base.source_node); | 22059 | resolve_top_level_decl(ira->codegen, tld, instruction->base.source_node, true); |
| 21868 | if (tld->resolution == TldResolutionInvalid) | 22060 | if (tld->resolution == TldResolutionInvalid) |
| 21869 | return ira->codegen->invalid_instruction; | 22061 | return ira->codegen->invalid_instruction; |
| 21870 | 22062 |
src/ir.hpp+2-1| ... | @@ -16,7 +16,8 @@ bool ir_gen_fn(CodeGen *g, ZigFn *fn_entry); | ... | @@ -16,7 +16,8 @@ bool ir_gen_fn(CodeGen *g, ZigFn *fn_entry); |
| 16 | ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, | 16 | ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, |
| 17 | ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, | 17 | ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, |
| 18 | ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, | 18 | ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, |
| 19 | IrExecutable *parent_exec, AstNode *expected_type_source_node); | 19 | IrExecutable *parent_exec, AstNode *expected_type_source_node, bool allow_lazy); |
| 20 | Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ConstExprValue *val); | ||
| 20 | 21 | ||
| 21 | ZigType *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable, | 22 | ZigType *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable, |
| 22 | ZigType *expected_type, AstNode *expected_type_source_node); | 23 | ZigType *expected_type, AstNode *expected_type_source_node); |