| ... | ... | @@ -566,6 +566,7 @@ ZigType *get_optional_type(CodeGen *g, ZigType *child_type) { |
| 566 | 566 | } |
| 567 | 567 | |
| 568 | 568 | entry->data.maybe.child_type = child_type; |
| 569 | entry->data.maybe.resolve_status = ResolveStatusSizeKnown; |
| 569 | 570 | |
| 570 | 571 | child_type->optional_parent = entry; |
| 571 | 572 | return entry; |
| ... | ... | @@ -1055,9 +1056,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue |
| 1055 | 1056 | zig_unreachable(); |
| 1056 | 1057 | case LazyValueIdSliceType: { |
| 1057 | 1058 | LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy); |
| 1058 | | if (type_is_invalid(lazy_slice_type->elem_type)) |
| 1059 | | return ReqCompTimeInvalid; |
| 1060 | | return type_requires_comptime(g, lazy_slice_type->elem_type); |
| 1059 | return type_val_resolve_requires_comptime(g, &lazy_slice_type->elem_type->value); |
| 1061 | 1060 | } |
| 1062 | 1061 | case LazyValueIdPtrType: { |
| 1063 | 1062 | LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy); |
| ... | ... | @@ -1099,6 +1098,42 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue |
| 1099 | 1098 | zig_unreachable(); |
| 1100 | 1099 | } |
| 1101 | 1100 | |
| 1101 | static Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ConstExprValue *type_val, |
| 1102 | size_t *abi_size, size_t *size_in_bits) |
| 1103 | { |
| 1104 | Error err; |
| 1105 | if (type_val->data.x_lazy->id == LazyValueIdOptType) { |
| 1106 | if ((err = ir_resolve_lazy(g, source_node, type_val))) |
| 1107 | return err; |
| 1108 | } |
| 1109 | if (type_val->special != ConstValSpecialLazy) { |
| 1110 | assert(type_val->special == ConstValSpecialStatic); |
| 1111 | ZigType *ty = type_val->data.x_type; |
| 1112 | if ((err = type_resolve(g, ty, ResolveStatusSizeKnown))) |
| 1113 | return err; |
| 1114 | *abi_size = ty->abi_size; |
| 1115 | *size_in_bits = ty->size_in_bits; |
| 1116 | return ErrorNone; |
| 1117 | } |
| 1118 | switch (type_val->data.x_lazy->id) { |
| 1119 | case LazyValueIdInvalid: |
| 1120 | case LazyValueIdAlignOf: |
| 1121 | zig_unreachable(); |
| 1122 | case LazyValueIdSliceType: |
| 1123 | *abi_size = g->builtin_types.entry_usize->abi_size * 2; |
| 1124 | *size_in_bits = g->builtin_types.entry_usize->size_in_bits * 2; |
| 1125 | return ErrorNone; |
| 1126 | case LazyValueIdPtrType: |
| 1127 | case LazyValueIdFnType: |
| 1128 | *abi_size = g->builtin_types.entry_usize->abi_size; |
| 1129 | *size_in_bits = g->builtin_types.entry_usize->size_in_bits; |
| 1130 | return ErrorNone; |
| 1131 | case LazyValueIdOptType: |
| 1132 | zig_unreachable(); |
| 1133 | } |
| 1134 | zig_unreachable(); |
| 1135 | } |
| 1136 | |
| 1102 | 1137 | Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t *abi_align) { |
| 1103 | 1138 | Error err; |
| 1104 | 1139 | if (type_val->special != ConstValSpecialLazy) { |
| ... | ... | @@ -1767,6 +1802,17 @@ static size_t get_abi_size_bytes(size_t size_in_bits, size_t pointer_size_bytes) |
| 1767 | 1802 | return align_forward(store_size_bytes, abi_align); |
| 1768 | 1803 | } |
| 1769 | 1804 | |
| 1805 | ZigType *resolve_struct_field_type(CodeGen *g, TypeStructField *struct_field) { |
| 1806 | Error err; |
| 1807 | if (struct_field->type_entry == nullptr) { |
| 1808 | if ((err = ir_resolve_lazy(g, struct_field->decl_node, struct_field->type_val))) { |
| 1809 | return nullptr; |
| 1810 | } |
| 1811 | struct_field->type_entry = struct_field->type_val->data.x_type; |
| 1812 | } |
| 1813 | return struct_field->type_entry; |
| 1814 | } |
| 1815 | |
| 1770 | 1816 | static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| 1771 | 1817 | assert(struct_type->id == ZigTypeIdStruct); |
| 1772 | 1818 | |
| ... | ... | @@ -1801,40 +1847,6 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| 1801 | 1847 | |
| 1802 | 1848 | uint32_t *host_int_bytes = packed ? allocate<uint32_t>(struct_type->data.structure.gen_field_count) : nullptr; |
| 1803 | 1849 | |
| 1804 | | // Resolve types for fields and then resolve sizes of all the field types. |
| 1805 | | // This is done before the offset loop because the offset loop has to look ahead. |
| 1806 | | for (size_t i = 0; i < field_count; i += 1) { |
| 1807 | | AstNode *field_source_node = decl_node->data.container_decl.fields.at(i); |
| 1808 | | TypeStructField *field = &struct_type->data.structure.fields[i]; |
| 1809 | | |
| 1810 | | if ((err = ir_resolve_lazy(g, field_source_node, field->type_val))) { |
| 1811 | | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 1812 | | return err; |
| 1813 | | } |
| 1814 | | field->type_entry = field->type_val->data.x_type; |
| 1815 | | |
| 1816 | | if ((err = type_resolve(g, field->type_entry, ResolveStatusSizeKnown))) { |
| 1817 | | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 1818 | | return err; |
| 1819 | | } |
| 1820 | | |
| 1821 | | if (struct_type->data.structure.layout == ContainerLayoutExtern && |
| 1822 | | !type_allowed_in_extern(g, field->type_entry)) |
| 1823 | | { |
| 1824 | | add_node_error(g, field_source_node, |
| 1825 | | buf_sprintf("extern structs cannot contain fields of type '%s'", |
| 1826 | | buf_ptr(&field->type_entry->name))); |
| 1827 | | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 1828 | | return ErrorSemanticAnalyzeFail; |
| 1829 | | } else if (packed) { |
| 1830 | | if ((err = emit_error_unless_type_allowed_in_packed_struct(g, field->type_entry, field_source_node))) { |
| 1831 | | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 1832 | | return err; |
| 1833 | | } |
| 1834 | | } |
| 1835 | | |
| 1836 | | } |
| 1837 | | |
| 1838 | 1850 | size_t packed_bits_offset = 0; |
| 1839 | 1851 | size_t next_offset = 0; |
| 1840 | 1852 | size_t first_packed_bits_offset_misalign = SIZE_MAX; |
| ... | ... | @@ -1847,13 +1859,25 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| 1847 | 1859 | TypeStructField *field = &struct_type->data.structure.fields[i]; |
| 1848 | 1860 | if (field->gen_index == SIZE_MAX) |
| 1849 | 1861 | continue; |
| 1850 | | ZigType *field_type = field->type_entry; |
| 1851 | | assert(field_type != nullptr); |
| 1852 | 1862 | |
| 1853 | 1863 | field->gen_index = gen_field_index; |
| 1854 | 1864 | field->offset = next_offset; |
| 1855 | 1865 | |
| 1856 | 1866 | if (packed) { |
| 1867 | ZigType *field_type = resolve_struct_field_type(g, field); |
| 1868 | if (field_type == nullptr) { |
| 1869 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 1870 | return err; |
| 1871 | } |
| 1872 | if ((err = type_resolve(g, field->type_entry, ResolveStatusSizeKnown))) { |
| 1873 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 1874 | return err; |
| 1875 | } |
| 1876 | if ((err = emit_error_unless_type_allowed_in_packed_struct(g, field->type_entry, field->decl_node))) { |
| 1877 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 1878 | return err; |
| 1879 | } |
| 1880 | |
| 1857 | 1881 | size_t field_size_in_bits = type_size_bits(g, field_type); |
| 1858 | 1882 | size_t next_packed_bits_offset = packed_bits_offset + field_size_in_bits; |
| 1859 | 1883 | |
| ... | ... | @@ -1889,6 +1913,15 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| 1889 | 1913 | } |
| 1890 | 1914 | packed_bits_offset = next_packed_bits_offset; |
| 1891 | 1915 | } else { |
| 1916 | size_t field_abi_size; |
| 1917 | size_t field_size_in_bits; |
| 1918 | if ((err = type_val_resolve_abi_size(g, field->decl_node, field->type_val, |
| 1919 | &field_abi_size, &field_size_in_bits))) |
| 1920 | { |
| 1921 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 1922 | return err; |
| 1923 | } |
| 1924 | |
| 1892 | 1925 | gen_field_index += 1; |
| 1893 | 1926 | size_t next_src_field_index = i + 1; |
| 1894 | 1927 | for (; next_src_field_index < field_count; next_src_field_index += 1) { |
| ... | ... | @@ -1898,7 +1931,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| 1898 | 1931 | } |
| 1899 | 1932 | size_t next_align = (next_src_field_index == field_count) ? |
| 1900 | 1933 | abi_align : struct_type->data.structure.fields[next_src_field_index].align; |
| 1901 | | next_offset = next_field_offset(next_offset, abi_align, field_type->abi_size, next_align); |
| 1934 | next_offset = next_field_offset(next_offset, abi_align, field_abi_size, next_align); |
| 1902 | 1935 | size_in_bits = next_offset * 8; |
| 1903 | 1936 | } |
| 1904 | 1937 | } |
| ... | ... | @@ -1917,6 +1950,36 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| 1917 | 1950 | struct_type->data.structure.resolve_loop_flag_other = false; |
| 1918 | 1951 | struct_type->data.structure.host_int_bytes = host_int_bytes; |
| 1919 | 1952 | |
| 1953 | |
| 1954 | // Resolve types for fields |
| 1955 | if (!packed) { |
| 1956 | for (size_t i = 0; i < field_count; i += 1) { |
| 1957 | TypeStructField *field = &struct_type->data.structure.fields[i]; |
| 1958 | ZigType *field_type = resolve_struct_field_type(g, field); |
| 1959 | if (field_type == nullptr) { |
| 1960 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 1961 | return err; |
| 1962 | } |
| 1963 | |
| 1964 | if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) { |
| 1965 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 1966 | return err; |
| 1967 | } |
| 1968 | |
| 1969 | if (struct_type->data.structure.layout == ContainerLayoutExtern && |
| 1970 | !type_allowed_in_extern(g, field_type)) |
| 1971 | { |
| 1972 | add_node_error(g, field->decl_node, |
| 1973 | buf_sprintf("extern structs cannot contain fields of type '%s'", |
| 1974 | buf_ptr(&field_type->name))); |
| 1975 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 1976 | return ErrorSemanticAnalyzeFail; |
| 1977 | } |
| 1978 | |
| 1979 | } |
| 1980 | } |
| 1981 | |
| 1982 | |
| 1920 | 1983 | return ErrorNone; |
| 1921 | 1984 | } |
| 1922 | 1985 | |
| ... | ... | @@ -7669,8 +7732,11 @@ static void resolve_llvm_types_integer(CodeGen *g, ZigType *type) { |
| 7669 | 7732 | type->llvm_type = LLVMIntType(type->size_in_bits); |
| 7670 | 7733 | } |
| 7671 | 7734 | |
| 7672 | | static void resolve_llvm_types_optional(CodeGen *g, ZigType *type) { |
| 7673 | | if (type->llvm_di_type != nullptr) return; |
| 7735 | static void resolve_llvm_types_optional(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) { |
| 7736 | assert(type->id == ZigTypeIdOptional); |
| 7737 | assert(type->data.maybe.resolve_status != ResolveStatusInvalid); |
| 7738 | assert(type->data.maybe.resolve_status >= ResolveStatusSizeKnown); |
| 7739 | if (type->data.maybe.resolve_status >= wanted_resolve_status) return; |
| 7674 | 7740 | |
| 7675 | 7741 | LLVMTypeRef bool_llvm_type = get_llvm_type(g, g->builtin_types.entry_bool); |
| 7676 | 7742 | ZigLLVMDIType *bool_llvm_di_type = get_llvm_di_type(g, g->builtin_types.entry_bool); |
| ... | ... | @@ -7679,30 +7745,41 @@ static void resolve_llvm_types_optional(CodeGen *g, ZigType *type) { |
| 7679 | 7745 | if (!type_has_bits(child_type)) { |
| 7680 | 7746 | type->llvm_type = bool_llvm_type; |
| 7681 | 7747 | type->llvm_di_type = bool_llvm_di_type; |
| 7748 | type->data.maybe.resolve_status = ResolveStatusLLVMFull; |
| 7682 | 7749 | return; |
| 7683 | 7750 | } |
| 7684 | 7751 | |
| 7685 | | LLVMTypeRef child_llvm_type = get_llvm_type(g, child_type); |
| 7686 | | ZigLLVMDIType *child_llvm_di_type = get_llvm_di_type(g, child_type); |
| 7687 | | |
| 7688 | 7752 | if (type_is_nonnull_ptr(child_type) || child_type->id == ZigTypeIdErrorSet) { |
| 7689 | | type->llvm_type = child_llvm_type; |
| 7690 | | type->llvm_di_type = child_llvm_di_type; |
| 7753 | type->llvm_type = get_llvm_type(g, child_type); |
| 7754 | type->llvm_di_type = get_llvm_di_type(g, child_type); |
| 7755 | type->data.maybe.resolve_status = ResolveStatusLLVMFull; |
| 7691 | 7756 | return; |
| 7692 | 7757 | } |
| 7693 | 7758 | |
| 7759 | ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit); |
| 7760 | ZigLLVMDIFile *di_file = nullptr; |
| 7761 | unsigned line = 0; |
| 7762 | |
| 7763 | if (type->data.maybe.resolve_status < ResolveStatusLLVMFwdDecl) { |
| 7764 | type->llvm_type = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&type->name)); |
| 7765 | unsigned dwarf_kind = ZigLLVMTag_DW_structure_type(); |
| 7766 | type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, |
| 7767 | dwarf_kind, buf_ptr(&type->name), |
| 7768 | compile_unit_scope, di_file, line); |
| 7769 | |
| 7770 | type->data.maybe.resolve_status = ResolveStatusLLVMFwdDecl; |
| 7771 | if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return; |
| 7772 | } |
| 7773 | |
| 7774 | LLVMTypeRef child_llvm_type = get_llvm_type(g, child_type); |
| 7775 | ZigLLVMDIType *child_llvm_di_type = get_llvm_di_type(g, child_type); |
| 7776 | if (type->data.maybe.resolve_status >= wanted_resolve_status) return; |
| 7777 | |
| 7694 | 7778 | LLVMTypeRef elem_types[] = { |
| 7695 | 7779 | get_llvm_type(g, child_type), |
| 7696 | 7780 | LLVMInt1Type(), |
| 7697 | 7781 | }; |
| 7698 | | type->llvm_type = LLVMStructType(elem_types, 2, false); |
| 7699 | | |
| 7700 | | ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit); |
| 7701 | | ZigLLVMDIFile *di_file = nullptr; |
| 7702 | | unsigned line = 0; |
| 7703 | | type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, |
| 7704 | | ZigLLVMTag_DW_structure_type(), buf_ptr(&type->name), |
| 7705 | | compile_unit_scope, di_file, line); |
| 7782 | LLVMStructSetBody(type->llvm_type, elem_types, 2, false); |
| 7706 | 7783 | |
| 7707 | 7784 | uint64_t val_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, child_llvm_type); |
| 7708 | 7785 | uint64_t val_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, child_llvm_type); |
| ... | ... | @@ -7737,6 +7814,7 @@ static void resolve_llvm_types_optional(CodeGen *g, ZigType *type) { |
| 7737 | 7814 | |
| 7738 | 7815 | ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type); |
| 7739 | 7816 | type->llvm_di_type = replacement_di_type; |
| 7817 | type->data.maybe.resolve_status = ResolveStatusLLVMFull; |
| 7740 | 7818 | } |
| 7741 | 7819 | |
| 7742 | 7820 | static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) { |
| ... | ... | @@ -8180,7 +8258,7 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r |
| 8180 | 8258 | case ZigTypeIdInt: |
| 8181 | 8259 | return resolve_llvm_types_integer(g, type); |
| 8182 | 8260 | case ZigTypeIdOptional: |
| 8183 | | return resolve_llvm_types_optional(g, type); |
| 8261 | return resolve_llvm_types_optional(g, type, wanted_resolve_status); |
| 8184 | 8262 | case ZigTypeIdErrorUnion: |
| 8185 | 8263 | return resolve_llvm_types_error_union(g, type); |
| 8186 | 8264 | case ZigTypeIdArray: |