authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-04-02 14:44:25-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-04-02 18:31:19-04:00
log5aee17e888c0db7ed0d220334f3adeff6e323cb2
tree27699680c82b9aadbb3b2b0e2b53bf74d5536af3
parentddb8aa73f542d3432538e6de466ac216c89fd12b
signaturelock-open Commit is signed but in an unrecognized format.

regression fixes and fix packed struct abi size


4 files changed, 179 insertions(+), 106 deletions(-)

doc/langref.html.in+4-4
...@@ -2112,8 +2112,8 @@ test "linked list" {...@@ -2112,8 +2112,8 @@ test "linked list" {
2112 <li>A {#link|packed enum#} field uses exactly the bit width of its integer tag type.</li>2112 <li>A {#link|packed enum#} field uses exactly the bit width of its integer tag type.</li>
2113 <li>A {#link|packed union#} field uses exactly the bit width of the union field with2113 <li>A {#link|packed union#} field uses exactly the bit width of the union field with
2114 the largest bit width.</li>2114 the largest bit width.</li>
2115 <li>Non-byte-aligned fields are packed into the smallest possible2115 <li>Non-ABI-aligned fields are packed into the smallest possible
2116 byte-aligned integers in accordance with the target endianness.2116 ABI-aligned integers in accordance with the target endianness.
2117 </li>2117 </li>
2118 </ul>2118 </ul>
2119 <p>2119 <p>
...@@ -2213,10 +2213,10 @@ fn bar(x: *const u3) u3 {...@@ -2213,10 +2213,10 @@ fn bar(x: *const u3) u3 {
2213 {#code_end#}2213 {#code_end#}
2214 <p>2214 <p>
2215 In this case, the function {#syntax#}bar{#endsyntax#} cannot be called becuse the pointer2215 In this case, the function {#syntax#}bar{#endsyntax#} cannot be called becuse the pointer
2216 to the non-byte-aligned field mentions the bit offset, but the function expects a byte-aligned pointer.2216 to the non-ABI-aligned field mentions the bit offset, but the function expects an ABI-aligned pointer.
2217 </p>2217 </p>
2218 <p>2218 <p>
2219 Pointers to non-byte-aligned fields share the same address as the other fields within their host integer:2219 Pointers to non-ABI-aligned fields share the same address as the other fields within their host integer:
2220 </p>2220 </p>
2221 {#code_begin|test#}2221 {#code_begin|test#}
2222const std = @import("std");2222const std = @import("std");
src/all_types.hpp+2
...@@ -1079,6 +1079,8 @@ enum ResolveStatus {...@@ -1079,6 +1079,8 @@ enum ResolveStatus {
1079 ResolveStatusZeroBitsKnown,1079 ResolveStatusZeroBitsKnown,
1080 ResolveStatusAlignmentKnown,1080 ResolveStatusAlignmentKnown,
1081 ResolveStatusSizeKnown,1081 ResolveStatusSizeKnown,
1082 ResolveStatusLLVMFwdDecl,
1083 ResolveStatusLLVMFull,
1082};1084};
10831085
1084struct ZigPackage {1086struct ZigPackage {
src/analyze.cpp+162-97
...@@ -27,6 +27,7 @@ static Error ATTRIBUTE_MUST_USE resolve_enum_zero_bits(CodeGen *g, ZigType *enum...@@ -27,6 +27,7 @@ static Error ATTRIBUTE_MUST_USE resolve_enum_zero_bits(CodeGen *g, ZigType *enum
27static Error ATTRIBUTE_MUST_USE resolve_union_zero_bits(CodeGen *g, ZigType *union_type);27static Error ATTRIBUTE_MUST_USE resolve_union_zero_bits(CodeGen *g, ZigType *union_type);
28static Error ATTRIBUTE_MUST_USE resolve_union_alignment(CodeGen *g, ZigType *union_type);28static Error ATTRIBUTE_MUST_USE resolve_union_alignment(CodeGen *g, ZigType *union_type);
29static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry);29static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry);
30static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status);
3031
31static bool is_top_level_struct(ZigType *import) {32static bool is_top_level_struct(ZigType *import) {
32 return import->id == ZigTypeIdStruct && import->data.structure.root_struct != nullptr;33 return import->id == ZigTypeIdStruct && import->data.structure.root_struct != nullptr;
...@@ -278,6 +279,9 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {...@@ -278,6 +279,9 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
278 return type_entry->data.enumeration.zero_bits_known;279 return type_entry->data.enumeration.zero_bits_known;
279 case ResolveStatusSizeKnown:280 case ResolveStatusSizeKnown:
280 return type_entry->data.enumeration.complete;281 return type_entry->data.enumeration.complete;
282 case ResolveStatusLLVMFwdDecl:
283 case ResolveStatusLLVMFull:
284 return type_entry->llvm_di_type != nullptr;
281 }285 }
282 zig_unreachable();286 zig_unreachable();
283 case ZigTypeIdOpaque:287 case ZigTypeIdOpaque:
...@@ -1120,6 +1124,7 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType...@@ -1120,6 +1124,7 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
1120 ZigType *elem_type = type_entry->data.array.child_type;1124 ZigType *elem_type = type_entry->data.array.child_type;
1121 if ((err = emit_error_unless_type_allowed_in_packed_struct(g, elem_type, source_node)))1125 if ((err = emit_error_unless_type_allowed_in_packed_struct(g, elem_type, source_node)))
1122 return err;1126 return err;
1127 // TODO revisit this when doing https://github.com/ziglang/zig/issues/1512
1123 if (type_size(g, type_entry) * 8 == type_size_bits(g, type_entry))1128 if (type_size(g, type_entry) * 8 == type_size_bits(g, type_entry))
1124 return ErrorNone;1129 return ErrorNone;
1125 add_node_error(g, source_node,1130 add_node_error(g, source_node,
...@@ -1559,8 +1564,21 @@ ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_na...@@ -1559,8 +1564,21 @@ ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_na
1559 return struct_type;1564 return struct_type;
1560}1565}
15611566
1562static size_t get_store_size_in_bits(size_t size_in_bits) {1567static size_t get_store_size_bytes(size_t size_in_bits) {
1563 return ((size_in_bits + 7) / 8) * 8;1568 return (size_in_bits + 7) / 8;
1569}
1570
1571static size_t get_abi_align_bytes(size_t size_in_bits, size_t pointer_size_bytes) {
1572 size_t store_size_bytes = get_store_size_bytes(size_in_bits);
1573 if (store_size_bytes >= pointer_size_bytes)
1574 return pointer_size_bytes;
1575 return round_to_next_power_of_2(store_size_bytes);
1576}
1577
1578static size_t get_abi_size_bytes(size_t size_in_bits, size_t pointer_size_bytes) {
1579 size_t store_size_bytes = get_store_size_bytes(size_in_bits);
1580 size_t abi_align = get_abi_align_bytes(size_in_bits, pointer_size_bytes);
1581 return align_forward(store_size_bytes, abi_align);
1564}1582}
15651583
1566static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {1584static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
...@@ -1637,17 +1655,18 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {...@@ -1637,17 +1655,18 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
1637 field->bit_offset_in_host = packed_bits_offset - first_packed_bits_offset_misalign;1655 field->bit_offset_in_host = packed_bits_offset - first_packed_bits_offset_misalign;
16381656
1639 size_t full_bit_count = next_packed_bits_offset - first_packed_bits_offset_misalign;1657 size_t full_bit_count = next_packed_bits_offset - first_packed_bits_offset_misalign;
1640 if (get_store_size_in_bits(full_bit_count) == full_bit_count) {1658 size_t full_abi_size = get_abi_size_bytes(full_bit_count, g->pointer_size_bytes);
1641 // next field recovers store alignment1659 if (full_abi_size * 8 == full_bit_count) {
1642 host_int_bytes[gen_field_index] = full_bit_count / 8;1660 // next field recovers ABI alignment
1661 host_int_bytes[gen_field_index] = full_abi_size;
1643 gen_field_index += 1;1662 gen_field_index += 1;
1644 // TODO: https://github.com/ziglang/zig/issues/15121663 // TODO: https://github.com/ziglang/zig/issues/1512
1645 next_offset = next_field_offset(next_offset, abi_align, full_bit_count / 8, 1);1664 next_offset = next_field_offset(next_offset, abi_align, full_abi_size, 1);
1646 size_in_bits = next_offset * 8;1665 size_in_bits = next_offset * 8;
16471666
1648 first_packed_bits_offset_misalign = SIZE_MAX;1667 first_packed_bits_offset_misalign = SIZE_MAX;
1649 }1668 }
1650 } else if (get_store_size_in_bits(field_type->size_in_bits) != field_size_in_bits) {1669 } else if (get_abi_size_bytes(field_type->size_in_bits, g->pointer_size_bytes) * 8 != field_size_in_bits) {
1651 first_packed_bits_offset_misalign = packed_bits_offset;1670 first_packed_bits_offset_misalign = packed_bits_offset;
1652 field->bit_offset_in_host = 0;1671 field->bit_offset_in_host = 0;
1653 } else {1672 } else {
...@@ -1676,9 +1695,9 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {...@@ -1676,9 +1695,9 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
1676 }1695 }
1677 if (first_packed_bits_offset_misalign != SIZE_MAX) {1696 if (first_packed_bits_offset_misalign != SIZE_MAX) {
1678 size_t full_bit_count = packed_bits_offset - first_packed_bits_offset_misalign;1697 size_t full_bit_count = packed_bits_offset - first_packed_bits_offset_misalign;
1679 size_t store_bit_count = get_store_size_in_bits(full_bit_count);1698 size_t full_abi_size = get_abi_size_bytes(full_bit_count, g->pointer_size_bytes);
1680 next_offset = next_field_offset(next_offset, abi_align, store_bit_count / 8, 1);1699 next_offset = next_field_offset(next_offset, abi_align, full_abi_size, abi_align);
1681 host_int_bytes[gen_field_index] = store_bit_count / 8;1700 host_int_bytes[gen_field_index] = full_abi_size;
1682 gen_field_index += 1;1701 gen_field_index += 1;
1683 }1702 }
16841703
...@@ -4986,6 +5005,10 @@ Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) {...@@ -4986,6 +5005,10 @@ Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) {
4986 return resolve_union_type(g, ty);5005 return resolve_union_type(g, ty);
4987 }5006 }
4988 return ErrorNone;5007 return ErrorNone;
5008 case ResolveStatusLLVMFwdDecl:
5009 case ResolveStatusLLVMFull:
5010 resolve_llvm_types(g, ty, status);
5011 return ErrorNone;
4989 }5012 }
4990 zig_unreachable();5013 zig_unreachable();
4991}5014}
...@@ -6223,57 +6246,68 @@ Buf *type_h_name(ZigType *t) {...@@ -6223,57 +6246,68 @@ Buf *type_h_name(ZigType *t) {
6223 return type_bare_name(t);6246 return type_bare_name(t);
6224}6247}
62256248
6226static void resolve_llvm_types_slice(CodeGen *g, ZigType *type) {6249static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) {
6250 if (type->data.structure.resolve_status >= wanted_resolve_status) return;
6251
6227 ZigType *ptr_type = type->data.structure.fields[slice_ptr_index].type_entry;6252 ZigType *ptr_type = type->data.structure.fields[slice_ptr_index].type_entry;
6228 ZigType *child_type = ptr_type->data.pointer.child_type;6253 ZigType *child_type = ptr_type->data.pointer.child_type;
6254 ZigType *usize_type = g->builtin_types.entry_usize;
6255 LLVMTypeRef usize_llvm_type = get_llvm_type(g, usize_type);
6256 ZigLLVMDIType *usize_llvm_di_type = get_llvm_di_type(g, usize_type);
6257 ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit);
6258 ZigLLVMDIFile *di_file = nullptr;
6259 unsigned line = 0;
62296260
6230 if (ptr_type->data.pointer.is_const || ptr_type->data.pointer.is_volatile ||6261 if (type->data.structure.resolve_status < ResolveStatusLLVMFwdDecl) {
6231 ptr_type->data.pointer.explicit_alignment != 0 || ptr_type->data.pointer.allow_zero)6262 bool done = false;
6232 {6263 if (ptr_type->data.pointer.is_const || ptr_type->data.pointer.is_volatile ||
6233 ZigType *peer_ptr_type = get_pointer_to_type_extra(g, child_type, false, false,6264 ptr_type->data.pointer.explicit_alignment != 0 || ptr_type->data.pointer.allow_zero)
6234 PtrLenUnknown, 0, 0, 0, false);
6235 ZigType *peer_slice_type = get_slice_type(g, peer_ptr_type);
6236
6237 type->llvm_type = get_llvm_type(g, peer_slice_type);
6238 type->llvm_di_type = get_llvm_di_type(g, peer_slice_type);
6239 }
6240
6241 // If the child type is []const T then we need to make sure the type ref
6242 // and debug info is the same as if the child type were []T.
6243 if (is_slice(child_type)) {
6244 ZigType *child_ptr_type = child_type->data.structure.fields[slice_ptr_index].type_entry;
6245 assert(child_ptr_type->id == ZigTypeIdPointer);
6246 if (child_ptr_type->data.pointer.is_const || child_ptr_type->data.pointer.is_volatile ||
6247 child_ptr_type->data.pointer.explicit_alignment != 0 || child_ptr_type->data.pointer.allow_zero)
6248 {6265 {
6249 ZigType *grand_child_type = child_ptr_type->data.pointer.child_type;6266 ZigType *peer_ptr_type = get_pointer_to_type_extra(g, child_type, false, false,
6250 ZigType *bland_child_ptr_type = get_pointer_to_type_extra(g, grand_child_type, false, false,
6251 PtrLenUnknown, 0, 0, 0, false);
6252 ZigType *bland_child_slice = get_slice_type(g, bland_child_ptr_type);
6253 ZigType *peer_ptr_type = get_pointer_to_type_extra(g, bland_child_slice, false, false,
6254 PtrLenUnknown, 0, 0, 0, false);6267 PtrLenUnknown, 0, 0, 0, false);
6255 ZigType *peer_slice_type = get_slice_type(g, peer_ptr_type);6268 ZigType *peer_slice_type = get_slice_type(g, peer_ptr_type);
62566269
6257 type->llvm_type = get_llvm_type(g, peer_slice_type);6270 type->llvm_type = get_llvm_type(g, peer_slice_type);
6258 type->llvm_di_type = get_llvm_di_type(g, peer_slice_type);6271 type->llvm_di_type = get_llvm_di_type(g, peer_slice_type);
6272 done = true;
6259 }6273 }
6260 }
62616274
6262 if (type->llvm_type != nullptr)6275 // If the child type is []const T then we need to make sure the type ref
6263 return;6276 // and debug info is the same as if the child type were []T.
6277 if (is_slice(child_type)) {
6278 ZigType *child_ptr_type = child_type->data.structure.fields[slice_ptr_index].type_entry;
6279 assert(child_ptr_type->id == ZigTypeIdPointer);
6280 if (child_ptr_type->data.pointer.is_const || child_ptr_type->data.pointer.is_volatile ||
6281 child_ptr_type->data.pointer.explicit_alignment != 0 || child_ptr_type->data.pointer.allow_zero)
6282 {
6283 ZigType *grand_child_type = child_ptr_type->data.pointer.child_type;
6284 ZigType *bland_child_ptr_type = get_pointer_to_type_extra(g, grand_child_type, false, false,
6285 PtrLenUnknown, 0, 0, 0, false);
6286 ZigType *bland_child_slice = get_slice_type(g, bland_child_ptr_type);
6287 ZigType *peer_ptr_type = get_pointer_to_type_extra(g, bland_child_slice, false, false,
6288 PtrLenUnknown, 0, 0, 0, false);
6289 ZigType *peer_slice_type = get_slice_type(g, peer_ptr_type);
6290
6291 type->llvm_type = get_llvm_type(g, peer_slice_type);
6292 type->llvm_di_type = get_llvm_di_type(g, peer_slice_type);
6293 done = true;
6294 }
6295 }
62646296
6265 ZigType *usize_type = g->builtin_types.entry_usize;6297 if (done) {
6266 LLVMTypeRef usize_llvm_type = get_llvm_type(g, usize_type);6298 type->data.structure.resolve_status = ResolveStatusLLVMFull;
6267 ZigLLVMDIType *usize_llvm_di_type = get_llvm_di_type(g, usize_type);6299 return;
6300 }
62686301
6269 type->llvm_type = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&type->name));6302 type->llvm_type = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&type->name));
62706303
6271 ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit);6304 type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
6272 ZigLLVMDIFile *di_file = nullptr;6305 ZigLLVMTag_DW_structure_type(), buf_ptr(&type->name),
6273 unsigned line = 0;6306 compile_unit_scope, di_file, line);
6274 type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,6307
6275 ZigLLVMTag_DW_structure_type(), buf_ptr(&type->name),6308 type->data.structure.resolve_status = ResolveStatusLLVMFwdDecl;
6276 compile_unit_scope, di_file, line);6309 if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return;
6310 }
62776311
6278 if (!type_has_bits(child_type)) {6312 if (!type_has_bits(child_type)) {
6279 LLVMTypeRef element_types[] = {6313 LLVMTypeRef element_types[] = {
...@@ -6304,6 +6338,7 @@ static void resolve_llvm_types_slice(CodeGen *g, ZigType *type) {...@@ -6304,6 +6338,7 @@ static void resolve_llvm_types_slice(CodeGen *g, ZigType *type) {
63046338
6305 ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type);6339 ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type);
6306 type->llvm_di_type = replacement_di_type;6340 type->llvm_di_type = replacement_di_type;
6341 type->data.structure.resolve_status = ResolveStatusLLVMFull;
6307 return;6342 return;
6308 }6343 }
63096344
...@@ -6345,17 +6380,16 @@ static void resolve_llvm_types_slice(CodeGen *g, ZigType *type) {...@@ -6345,17 +6380,16 @@ static void resolve_llvm_types_slice(CodeGen *g, ZigType *type) {
63456380
6346 ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type);6381 ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type);
6347 type->llvm_di_type = replacement_di_type;6382 type->llvm_di_type = replacement_di_type;
6383 type->data.structure.resolve_status = ResolveStatusLLVMFull;
6348}6384}
63496385
6350static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) {6386static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveStatus wanted_resolve_status) {
6351 assert(struct_type->id == ZigTypeIdStruct);6387 assert(struct_type->id == ZigTypeIdStruct);
6352 assert(struct_type->data.structure.resolve_status != ResolveStatusInvalid);6388 assert(struct_type->data.structure.resolve_status != ResolveStatusInvalid);
6353 assert(struct_type->data.structure.resolve_status >= ResolveStatusSizeKnown);6389 assert(struct_type->data.structure.resolve_status >= ResolveStatusSizeKnown);
6354 assert(struct_type->data.structure.fields || struct_type->data.structure.src_field_count == 0);6390 assert(struct_type->data.structure.fields || struct_type->data.structure.src_field_count == 0);
6391 if (struct_type->data.structure.resolve_status >= wanted_resolve_status) return;
63556392
6356 // Do this early for the benefit of recursion.
6357 struct_type->llvm_type = type_has_bits(struct_type) ?
6358 LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&struct_type->name)) : LLVMVoidType();
6359 AstNode *decl_node = struct_type->data.structure.decl_node;6393 AstNode *decl_node = struct_type->data.structure.decl_node;
6360 ZigLLVMDIFile *di_file;6394 ZigLLVMDIFile *di_file;
6361 ZigLLVMDIScope *di_scope;6395 ZigLLVMDIScope *di_scope;
...@@ -6372,10 +6406,18 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) {...@@ -6372,10 +6406,18 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) {
6372 di_scope = ZigLLVMCompileUnitToScope(g->compile_unit);6406 di_scope = ZigLLVMCompileUnitToScope(g->compile_unit);
6373 line = 0;6407 line = 0;
6374 }6408 }
6375 unsigned dwarf_kind = ZigLLVMTag_DW_structure_type();6409
6376 struct_type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,6410 if (struct_type->data.structure.resolve_status < ResolveStatusLLVMFwdDecl) {
6377 dwarf_kind, buf_ptr(&struct_type->name),6411 struct_type->llvm_type = type_has_bits(struct_type) ?
6378 di_scope, di_file, line);6412 LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&struct_type->name)) : LLVMVoidType();
6413 unsigned dwarf_kind = ZigLLVMTag_DW_structure_type();
6414 struct_type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
6415 dwarf_kind, buf_ptr(&struct_type->name),
6416 di_scope, di_file, line);
6417
6418 struct_type->data.structure.resolve_status = ResolveStatusLLVMFwdDecl;
6419 if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return;
6420 }
63796421
6380 size_t field_count = struct_type->data.structure.src_field_count;6422 size_t field_count = struct_type->data.structure.src_field_count;
6381 size_t gen_field_count = struct_type->data.structure.gen_field_count;6423 size_t gen_field_count = struct_type->data.structure.gen_field_count;
...@@ -6402,14 +6444,15 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) {...@@ -6402,14 +6444,15 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) {
6402 // this field is not byte-aligned; it is part of the previous field with a bit offset6444 // this field is not byte-aligned; it is part of the previous field with a bit offset
64036445
6404 size_t full_bit_count = next_packed_bits_offset - first_packed_bits_offset_misalign;6446 size_t full_bit_count = next_packed_bits_offset - first_packed_bits_offset_misalign;
6405 if (get_store_size_in_bits(full_bit_count) == full_bit_count) {6447 size_t full_abi_size = get_abi_size_bytes(full_bit_count, g->pointer_size_bytes);
6406 // next field recovers store alignment6448 if (full_abi_size * 8 == full_bit_count) {
6449 // next field recovers ABI alignment
6407 element_types[gen_field_index] = LLVMIntType((unsigned)(full_bit_count));6450 element_types[gen_field_index] = LLVMIntType((unsigned)(full_bit_count));
6408 gen_field_index += 1;6451 gen_field_index += 1;
64096452
6410 first_packed_bits_offset_misalign = SIZE_MAX;6453 first_packed_bits_offset_misalign = SIZE_MAX;
6411 }6454 }
6412 } else if (get_store_size_in_bits(field_type->size_in_bits) != field_size_in_bits) {6455 } else if (get_abi_size_bytes(field_type->size_in_bits, g->pointer_size_bytes) * 8 != field_size_in_bits) {
6413 first_packed_bits_offset_misalign = packed_bits_offset;6456 first_packed_bits_offset_misalign = packed_bits_offset;
6414 } else {6457 } else {
6415 // This is a byte-aligned field (both start and end) in a packed struct.6458 // This is a byte-aligned field (both start and end) in a packed struct.
...@@ -6426,8 +6469,8 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) {...@@ -6426,8 +6469,8 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) {
6426 }6469 }
6427 if (first_packed_bits_offset_misalign != SIZE_MAX) {6470 if (first_packed_bits_offset_misalign != SIZE_MAX) {
6428 size_t full_bit_count = packed_bits_offset - first_packed_bits_offset_misalign;6471 size_t full_bit_count = packed_bits_offset - first_packed_bits_offset_misalign;
6429 size_t store_bit_count = get_store_size_in_bits(full_bit_count);6472 size_t full_abi_size = get_abi_size_bytes(full_bit_count, g->pointer_size_bytes);
6430 element_types[gen_field_index] = LLVMIntType((unsigned)store_bit_count);6473 element_types[gen_field_index] = LLVMIntType((unsigned)full_abi_size * 8);
6431 gen_field_index += 1;6474 gen_field_index += 1;
6432 }6475 }
64336476
...@@ -6466,7 +6509,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) {...@@ -6466,7 +6509,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) {
6466 debug_align_in_bits = 8 * type_struct_field->type_entry->abi_align;6509 debug_align_in_bits = 8 * type_struct_field->type_entry->abi_align;
6467 debug_offset_in_bits = 8 * type_struct_field->offset + type_struct_field->bit_offset_in_host;6510 debug_offset_in_bits = 8 * type_struct_field->offset + type_struct_field->bit_offset_in_host;
6468 } else {6511 } else {
6469 debug_size_in_bits = get_store_size_in_bits(field_type->size_in_bits);6512 debug_size_in_bits = 8 * get_store_size_bytes(field_type->size_in_bits);
6470 debug_align_in_bits = 8 * field_type->abi_align;6513 debug_align_in_bits = 8 * field_type->abi_align;
6471 debug_offset_in_bits = 8 * type_struct_field->offset;6514 debug_offset_in_bits = 8 * type_struct_field->offset;
6472 }6515 }
...@@ -6488,7 +6531,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) {...@@ -6488,7 +6531,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) {
6488 debug_field_index += 1;6531 debug_field_index += 1;
6489 }6532 }
64906533
6491 uint64_t debug_size_in_bits = get_store_size_in_bits(struct_type->size_in_bits);6534 uint64_t debug_size_in_bits = 8*get_store_size_bytes(struct_type->size_in_bits);
6492 uint64_t debug_align_in_bits = 8*struct_type->abi_align;6535 uint64_t debug_align_in_bits = 8*struct_type->abi_align;
6493 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,6536 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
6494 di_scope,6537 di_scope,
...@@ -6500,11 +6543,13 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) {...@@ -6500,11 +6543,13 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) {
65006543
6501 ZigLLVMReplaceTemporary(g->dbuilder, struct_type->llvm_di_type, replacement_di_type);6544 ZigLLVMReplaceTemporary(g->dbuilder, struct_type->llvm_di_type, replacement_di_type);
6502 struct_type->llvm_di_type = replacement_di_type;6545 struct_type->llvm_di_type = replacement_di_type;
6546 struct_type->data.structure.resolve_status = ResolveStatusLLVMFull;
6503}6547}
65046548
6505static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type) {6549static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type) {
6506 assert(!enum_type->data.enumeration.is_invalid);6550 assert(!enum_type->data.enumeration.is_invalid);
6507 assert(enum_type->data.enumeration.complete);6551 assert(enum_type->data.enumeration.complete);
6552 if (enum_type->llvm_di_type != nullptr) return;
65086553
6509 uint32_t field_count = enum_type->data.enumeration.src_field_count;6554 uint32_t field_count = enum_type->data.enumeration.src_field_count;
65106555
...@@ -6541,27 +6586,34 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type) {...@@ -6541,27 +6586,34 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type) {
6541 enum_type->llvm_type = get_llvm_type(g, tag_int_type);6586 enum_type->llvm_type = get_llvm_type(g, tag_int_type);
6542}6587}
65436588
6544static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type) {6589static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveStatus wanted_resolve_status) {
6590 if (union_type->data.unionation.resolve_status >= wanted_resolve_status) return;
6591
6545 ZigType *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member;6592 ZigType *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member;
6546 ZigType *tag_type = union_type->data.unionation.tag_type;6593 ZigType *tag_type = union_type->data.unionation.tag_type;
6547 if (most_aligned_union_member == nullptr) {6594 if (most_aligned_union_member == nullptr) {
6548 union_type->llvm_type = get_llvm_type(g, tag_type);6595 union_type->llvm_type = get_llvm_type(g, tag_type);
6549 union_type->llvm_di_type = get_llvm_di_type(g, tag_type);6596 union_type->llvm_di_type = get_llvm_di_type(g, tag_type);
6597 union_type->data.unionation.resolve_status = ResolveStatusLLVMFull;
6550 return;6598 return;
6551 }6599 }
65526600
6553 // Do this first for the benefit of recursive calls.
6554 union_type->llvm_type = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&union_type->name));
6555 Scope *scope = &union_type->data.unionation.decls_scope->base;6601 Scope *scope = &union_type->data.unionation.decls_scope->base;
6556 ZigType *import = get_scope_import(scope);6602 ZigType *import = get_scope_import(scope);
6557 AstNode *decl_node = union_type->data.unionation.decl_node;6603 AstNode *decl_node = union_type->data.unionation.decl_node;
6558 size_t line = decl_node ? decl_node->line : 0;
6559 unsigned dwarf_kind = ZigLLVMTag_DW_structure_type();
6560 union_type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
6561 dwarf_kind, buf_ptr(&union_type->name),
6562 ZigLLVMFileToScope(import->data.structure.root_struct->di_file),
6563 import->data.structure.root_struct->di_file, (unsigned)(line + 1));
65646604
6605 if (union_type->data.unionation.resolve_status < ResolveStatusLLVMFwdDecl) {
6606 union_type->llvm_type = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&union_type->name));
6607 size_t line = decl_node ? decl_node->line : 0;
6608 unsigned dwarf_kind = ZigLLVMTag_DW_structure_type();
6609 union_type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
6610 dwarf_kind, buf_ptr(&union_type->name),
6611 ZigLLVMFileToScope(import->data.structure.root_struct->di_file),
6612 import->data.structure.root_struct->di_file, (unsigned)(line + 1));
6613
6614 union_type->data.unionation.resolve_status = ResolveStatusLLVMFwdDecl;
6615 if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return;
6616 }
65656617
6566 uint32_t gen_field_count = union_type->data.unionation.gen_field_count;6618 uint32_t gen_field_count = union_type->data.unionation.gen_field_count;
6567 ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(gen_field_count);6619 ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(gen_field_count);
...@@ -6615,6 +6667,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type) {...@@ -6615,6 +6667,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type) {
66156667
6616 ZigLLVMReplaceTemporary(g->dbuilder, union_type->llvm_di_type, replacement_di_type);6668 ZigLLVMReplaceTemporary(g->dbuilder, union_type->llvm_di_type, replacement_di_type);
6617 union_type->llvm_di_type = replacement_di_type;6669 union_type->llvm_di_type = replacement_di_type;
6670 union_type->data.unionation.resolve_status = ResolveStatusLLVMFull;
6618 return;6671 return;
6619 }6672 }
66206673
...@@ -6685,9 +6738,12 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type) {...@@ -6685,9 +6738,12 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type) {
66856738
6686 ZigLLVMReplaceTemporary(g->dbuilder, union_type->llvm_di_type, replacement_di_type);6739 ZigLLVMReplaceTemporary(g->dbuilder, union_type->llvm_di_type, replacement_di_type);
6687 union_type->llvm_di_type = replacement_di_type;6740 union_type->llvm_di_type = replacement_di_type;
6741 union_type->data.unionation.resolve_status = ResolveStatusLLVMFull;
6688}6742}
66896743
6690static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type) {6744static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type) {
6745 if (type->llvm_di_type != nullptr) return;
6746
6691 ZigType *elem_type = type->data.pointer.child_type;6747 ZigType *elem_type = type->data.pointer.child_type;
66926748
6693 if (type->data.pointer.is_const || type->data.pointer.is_volatile ||6749 if (type->data.pointer.is_const || type->data.pointer.is_volatile ||
...@@ -6702,10 +6758,11 @@ static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type) {...@@ -6702,10 +6758,11 @@ static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type) {
6702 }6758 }
67036759
6704 if (type->data.pointer.host_int_bytes == 0) {6760 if (type->data.pointer.host_int_bytes == 0) {
6705 type->llvm_type = LLVMPointerType(get_llvm_type(g, elem_type), 0);6761 assertNoError(type_resolve(g, elem_type, ResolveStatusLLVMFwdDecl));
6706 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, type->llvm_type);6762 type->llvm_type = LLVMPointerType(elem_type->llvm_type, 0);
6707 uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, type->llvm_type);6763 uint64_t debug_size_in_bits = 8*get_store_size_bytes(type->size_in_bits);
6708 type->llvm_di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, get_llvm_di_type(g, elem_type),6764 uint64_t debug_align_in_bits = 8*type->abi_align;
6765 type->llvm_di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, elem_type->llvm_di_type,
6709 debug_size_in_bits, debug_align_in_bits, buf_ptr(&type->name));6766 debug_size_in_bits, debug_align_in_bits, buf_ptr(&type->name));
6710 } else {6767 } else {
6711 ZigType *host_int_type = get_int_type(g, false, type->data.pointer.host_int_bytes * 8);6768 ZigType *host_int_type = get_int_type(g, false, type->data.pointer.host_int_bytes * 8);
...@@ -6719,6 +6776,8 @@ static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type) {...@@ -6719,6 +6776,8 @@ static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type) {
6719}6776}
67206777
6721static void resolve_llvm_types_integer(CodeGen *g, ZigType *type) {6778static void resolve_llvm_types_integer(CodeGen *g, ZigType *type) {
6779 if (type->llvm_di_type != nullptr) return;
6780
6722 unsigned dwarf_tag;6781 unsigned dwarf_tag;
6723 if (type->data.integral.is_signed) {6782 if (type->data.integral.is_signed) {
6724 if (type->size_in_bits == 8) {6783 if (type->size_in_bits == 8) {
...@@ -6739,6 +6798,8 @@ static void resolve_llvm_types_integer(CodeGen *g, ZigType *type) {...@@ -6739,6 +6798,8 @@ static void resolve_llvm_types_integer(CodeGen *g, ZigType *type) {
6739}6798}
67406799
6741static void resolve_llvm_types_optional(CodeGen *g, ZigType *type) {6800static void resolve_llvm_types_optional(CodeGen *g, ZigType *type) {
6801 if (type->llvm_di_type != nullptr) return;
6802
6742 LLVMTypeRef bool_llvm_type = get_llvm_type(g, g->builtin_types.entry_bool);6803 LLVMTypeRef bool_llvm_type = get_llvm_type(g, g->builtin_types.entry_bool);
6743 ZigLLVMDIType *bool_llvm_di_type = get_llvm_di_type(g, g->builtin_types.entry_bool);6804 ZigLLVMDIType *bool_llvm_di_type = get_llvm_di_type(g, g->builtin_types.entry_bool);
67446805
...@@ -6807,6 +6868,8 @@ static void resolve_llvm_types_optional(CodeGen *g, ZigType *type) {...@@ -6807,6 +6868,8 @@ static void resolve_llvm_types_optional(CodeGen *g, ZigType *type) {
6807}6868}
68086869
6809static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) {6870static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) {
6871 if (type->llvm_di_type != nullptr) return;
6872
6810 ZigType *payload_type = type->data.error_union.payload_type;6873 ZigType *payload_type = type->data.error_union.payload_type;
6811 ZigType *err_set_type = type->data.error_union.err_set_type;6874 ZigType *err_set_type = type->data.error_union.err_set_type;
68126875
...@@ -6874,6 +6937,8 @@ static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) {...@@ -6874,6 +6937,8 @@ static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) {
6874}6937}
68756938
6876static void resolve_llvm_types_array(CodeGen *g, ZigType *type) {6939static void resolve_llvm_types_array(CodeGen *g, ZigType *type) {
6940 if (type->llvm_di_type != nullptr) return;
6941
6877 ZigType *elem_type = type->data.array.child_type;6942 ZigType *elem_type = type->data.array.child_type;
68786943
6879 // TODO https://github.com/ziglang/zig/issues/14246944 // TODO https://github.com/ziglang/zig/issues/1424
...@@ -6887,6 +6952,8 @@ static void resolve_llvm_types_array(CodeGen *g, ZigType *type) {...@@ -6887,6 +6952,8 @@ static void resolve_llvm_types_array(CodeGen *g, ZigType *type) {
6887}6952}
68886953
6889static void resolve_llvm_types_fn(CodeGen *g, ZigType *fn_type) {6954static void resolve_llvm_types_fn(CodeGen *g, ZigType *fn_type) {
6955 if (fn_type->llvm_di_type != nullptr) return;
6956
6890 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;6957 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
6891 bool first_arg_return = want_first_arg_sret(g, fn_type_id);6958 bool first_arg_return = want_first_arg_sret(g, fn_type_id);
6892 bool is_async = fn_type_id->cc == CallingConventionAsync;6959 bool is_async = fn_type_id->cc == CallingConventionAsync;
...@@ -7010,16 +7077,12 @@ static void resolve_llvm_types_anyerror(CodeGen *g) {...@@ -7010,16 +7077,12 @@ static void resolve_llvm_types_anyerror(CodeGen *g) {
7010 get_llvm_di_type(g, g->err_tag_type), "");7077 get_llvm_di_type(g, g->err_tag_type), "");
7011}7078}
70127079
7013static void resolve_llvm_types(CodeGen *g, ZigType *type) {7080static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) {
7014 assert(type_is_resolved(type, ResolveStatusSizeKnown));7081 assert(type->id == ZigTypeIdOpaque || type_is_resolved(type, ResolveStatusSizeKnown));
7082 assert(wanted_resolve_status > ResolveStatusSizeKnown);
7015 switch (type->id) {7083 switch (type->id) {
7016 case ZigTypeIdInvalid:7084 case ZigTypeIdInvalid:
7017 case ZigTypeIdFloat:
7018 case ZigTypeIdOpaque:
7019 case ZigTypeIdMetaType:7085 case ZigTypeIdMetaType:
7020 case ZigTypeIdVoid:
7021 case ZigTypeIdBool:
7022 case ZigTypeIdUnreachable:
7023 case ZigTypeIdComptimeFloat:7086 case ZigTypeIdComptimeFloat:
7024 case ZigTypeIdComptimeInt:7087 case ZigTypeIdComptimeInt:
7025 case ZigTypeIdEnumLiteral:7088 case ZigTypeIdEnumLiteral:
...@@ -7028,18 +7091,26 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type) {...@@ -7028,18 +7091,26 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type) {
7028 case ZigTypeIdBoundFn:7091 case ZigTypeIdBoundFn:
7029 case ZigTypeIdArgTuple:7092 case ZigTypeIdArgTuple:
7030 zig_unreachable();7093 zig_unreachable();
7094 case ZigTypeIdFloat:
7095 case ZigTypeIdOpaque:
7096 case ZigTypeIdVoid:
7097 case ZigTypeIdBool:
7098 case ZigTypeIdUnreachable:
7099 assert(type->llvm_di_type != nullptr);
7100 return;
7031 case ZigTypeIdStruct:7101 case ZigTypeIdStruct:
7032 if (type->data.structure.is_slice)7102 if (type->data.structure.is_slice)
7033 return resolve_llvm_types_slice(g, type);7103 return resolve_llvm_types_slice(g, type, wanted_resolve_status);
7034 else7104 else
7035 return resolve_llvm_types_struct(g, type);7105 return resolve_llvm_types_struct(g, type, wanted_resolve_status);
7036 case ZigTypeIdEnum:7106 case ZigTypeIdEnum:
7037 return resolve_llvm_types_enum(g, type);7107 return resolve_llvm_types_enum(g, type);
7038 case ZigTypeIdUnion:7108 case ZigTypeIdUnion:
7039 return resolve_llvm_types_union(g, type);7109 return resolve_llvm_types_union(g, type, wanted_resolve_status);
7040 case ZigTypeIdPointer:7110 case ZigTypeIdPointer:
7041 return resolve_llvm_types_pointer(g, type);7111 return resolve_llvm_types_pointer(g, type);
7042 case ZigTypeIdPromise: {7112 case ZigTypeIdPromise: {
7113 if (type->llvm_di_type != nullptr) return;
7043 ZigType *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, false);7114 ZigType *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, false);
7044 type->llvm_type = get_llvm_type(g, u8_ptr_type);7115 type->llvm_type = get_llvm_type(g, u8_ptr_type);
7045 type->llvm_di_type = get_llvm_di_type(g, u8_ptr_type);7116 type->llvm_di_type = get_llvm_di_type(g, u8_ptr_type);
...@@ -7056,6 +7127,8 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type) {...@@ -7056,6 +7127,8 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type) {
7056 case ZigTypeIdFn:7127 case ZigTypeIdFn:
7057 return resolve_llvm_types_fn(g, type);7128 return resolve_llvm_types_fn(g, type);
7058 case ZigTypeIdErrorSet: {7129 case ZigTypeIdErrorSet: {
7130 if (type->llvm_di_type != nullptr) return;
7131
7059 if (g->builtin_types.entry_global_error_set->llvm_type == nullptr) {7132 if (g->builtin_types.entry_global_error_set->llvm_type == nullptr) {
7060 resolve_llvm_types_anyerror(g);7133 resolve_llvm_types_anyerror(g);
7061 }7134 }
...@@ -7064,6 +7137,8 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type) {...@@ -7064,6 +7137,8 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type) {
7064 return;7137 return;
7065 }7138 }
7066 case ZigTypeIdVector: {7139 case ZigTypeIdVector: {
7140 if (type->llvm_di_type != nullptr) return;
7141
7067 type->llvm_type = LLVMVectorType(get_llvm_type(g, type->data.vector.elem_type), type->data.vector.len);7142 type->llvm_type = LLVMVectorType(get_llvm_type(g, type->data.vector.elem_type), type->data.vector.len);
7068 type->llvm_di_type = ZigLLVMDIBuilderCreateVectorType(g->dbuilder, type->size_in_bits,7143 type->llvm_di_type = ZigLLVMDIBuilderCreateVectorType(g->dbuilder, type->size_in_bits,
7069 type->abi_align, get_llvm_di_type(g, type->data.vector.elem_type), type->data.vector.len);7144 type->abi_align, get_llvm_di_type(g, type->data.vector.elem_type), type->data.vector.len);
...@@ -7074,23 +7149,13 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type) {...@@ -7074,23 +7149,13 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type) {
7074}7149}
70757150
7076LLVMTypeRef get_llvm_type(CodeGen *g, ZigType *type) {7151LLVMTypeRef get_llvm_type(CodeGen *g, ZigType *type) {
7077 if (type->llvm_type != nullptr)7152 assertNoError(type_resolve(g, type, ResolveStatusLLVMFull));
7078 return type->llvm_type;
7079 resolve_llvm_types(g, type);
7080 assert(type->llvm_type != nullptr);
7081 assert(type->llvm_di_type != nullptr);
7082 assert(type->abi_size == 0 || type->abi_size == LLVMABISizeOfType(g->target_data_ref, type->llvm_type));7153 assert(type->abi_size == 0 || type->abi_size == LLVMABISizeOfType(g->target_data_ref, type->llvm_type));
7083 assert(type->abi_align == 0 || type->abi_align == LLVMABIAlignmentOfType(g->target_data_ref, type->llvm_type));7154 assert(type->abi_align == 0 || type->abi_align == LLVMABIAlignmentOfType(g->target_data_ref, type->llvm_type));
7084 return type->llvm_type;7155 return type->llvm_type;
7085}7156}
70867157
7087ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type) {7158ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type) {
7088 if (type->llvm_di_type != nullptr)7159 assertNoError(type_resolve(g, type, ResolveStatusLLVMFull));
7089 return type->llvm_di_type;
7090 resolve_llvm_types(g, type);
7091 assert(type->llvm_type != nullptr);
7092 assert(type->llvm_di_type != nullptr);
7093 assert(type->abi_size == 0 || type->abi_size == LLVMABISizeOfType(g->target_data_ref, type->llvm_type));
7094 assert(type->abi_align == 0 || type->abi_align == LLVMABIAlignmentOfType(g->target_data_ref, type->llvm_type));
7095 return type->llvm_di_type;7160 return type->llvm_di_type;
7096}7161}
test/stage1/behavior/struct.zig+11-5
...@@ -256,8 +256,8 @@ const Foo96Bits = packed struct {...@@ -256,8 +256,8 @@ const Foo96Bits = packed struct {
256256
257test "packed struct 24bits" {257test "packed struct 24bits" {
258 comptime {258 comptime {
259 expect(@sizeOf(Foo24Bits) == 3);259 expect(@sizeOf(Foo24Bits) == 4);
260 expect(@sizeOf(Foo96Bits) == 12);260 expect(@sizeOf(Foo96Bits) == 16);
261 }261 }
262262
263 var value = Foo96Bits{263 var value = Foo96Bits{
...@@ -291,16 +291,22 @@ test "packed struct 24bits" {...@@ -291,16 +291,22 @@ test "packed struct 24bits" {
291 expect(value.d == 1);291 expect(value.d == 1);
292}292}
293293
294const Foo32Bits = packed struct {
295 field: u24,
296 pad: u8,
297};
298
294const FooArray24Bits = packed struct {299const FooArray24Bits = packed struct {
295 a: u16,300 a: u16,
296 b: [2]Foo24Bits,301 b: [2]Foo32Bits,
297 c: u16,302 c: u16,
298};303};
299304
305// TODO revisit this test when doing https://github.com/ziglang/zig/issues/1512
300test "packed array 24bits" {306test "packed array 24bits" {
301 comptime {307 comptime {
302 expect(@sizeOf([9]Foo24Bits) == 9 * 3);308 expect(@sizeOf([9]Foo32Bits) == 9 * 4);
303 expect(@sizeOf(FooArray24Bits) == 2 + 2 * 3 + 2);309 expect(@sizeOf(FooArray24Bits) == 2 + 2 * 4 + 2);
304 }310 }
305311
306 var bytes = []u8{0} ** (@sizeOf(FooArray24Bits) + 1);312 var bytes = []u8{0} ** (@sizeOf(FooArray24Bits) + 1);