| ... | ... | @@ -1056,7 +1056,7 @@ pub const CType = extern union { |
| 1056 | 1056 | } |
| 1057 | 1057 | }, |
| 1058 | 1058 | |
| 1059 | | .Struct, .Union => |zig_tag| if (ty.containerLayout() == .Packed) { |
| 1059 | .Struct, .Union => |zig_ty_tag| if (ty.containerLayout() == .Packed) { |
| 1060 | 1060 | if (ty.castTag(.@"struct")) |struct_obj| { |
| 1061 | 1061 | try self.initType(struct_obj.data.backing_int_ty, kind, lookup); |
| 1062 | 1062 | } else { |
| ... | ... | @@ -1068,9 +1068,13 @@ pub const CType = extern union { |
| 1068 | 1068 | } |
| 1069 | 1069 | } else if (ty.isTupleOrAnonStruct()) { |
| 1070 | 1070 | if (lookup.isMutable()) { |
| 1071 | | for (0..ty.structFieldCount()) |field_i| { |
| 1071 | for (0..switch (zig_ty_tag) { |
| 1072 | .Struct => ty.structFieldCount(), |
| 1073 | .Union => ty.unionFields().count(), |
| 1074 | else => unreachable, |
| 1075 | }) |field_i| { |
| 1072 | 1076 | const field_ty = ty.structFieldType(field_i); |
| 1073 | | if (ty.structFieldIsComptime(field_i) or |
| 1077 | if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or |
| 1074 | 1078 | !field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 1075 | 1079 | _ = try lookup.typeToIndex(field_ty, switch (kind) { |
| 1076 | 1080 | .forward, .forward_parameter => .forward, |
| ... | ... | @@ -1086,14 +1090,22 @@ pub const CType = extern union { |
| 1086 | 1090 | } |
| 1087 | 1091 | } |
| 1088 | 1092 | self.init(switch (kind) { |
| 1089 | | .forward, .forward_parameter => .fwd_anon_struct, |
| 1090 | | .complete, .parameter, .global => .anon_struct, |
| 1093 | .forward, .forward_parameter => switch (zig_ty_tag) { |
| 1094 | .Struct => .fwd_anon_struct, |
| 1095 | .Union => .fwd_anon_union, |
| 1096 | else => unreachable, |
| 1097 | }, |
| 1098 | .complete, .parameter, .global => switch (zig_ty_tag) { |
| 1099 | .Struct => .anon_struct, |
| 1100 | .Union => .anon_union, |
| 1101 | else => unreachable, |
| 1102 | }, |
| 1091 | 1103 | .payload => unreachable, |
| 1092 | 1104 | }); |
| 1093 | 1105 | } else { |
| 1094 | 1106 | const tag_ty = ty.unionTagTypeSafety(); |
| 1095 | 1107 | const is_tagged_union_wrapper = kind != .payload and tag_ty != null; |
| 1096 | | const is_struct = zig_tag == .Struct or is_tagged_union_wrapper; |
| 1108 | const is_struct = zig_ty_tag == .Struct or is_tagged_union_wrapper; |
| 1097 | 1109 | switch (kind) { |
| 1098 | 1110 | .forward, .forward_parameter => { |
| 1099 | 1111 | self.storage = .{ .fwd = .{ |
| ... | ... | @@ -1138,7 +1150,7 @@ pub const CType = extern union { |
| 1138 | 1150 | self.init(.void); |
| 1139 | 1151 | } else { |
| 1140 | 1152 | var is_packed = false; |
| 1141 | | for (0..switch (zig_tag) { |
| 1153 | for (0..switch (zig_ty_tag) { |
| 1142 | 1154 | .Struct => ty.structFieldCount(), |
| 1143 | 1155 | .Union => ty.unionFields().count(), |
| 1144 | 1156 | else => unreachable, |
| ... | ... | @@ -1181,10 +1193,10 @@ pub const CType = extern union { |
| 1181 | 1193 | } |
| 1182 | 1194 | }, |
| 1183 | 1195 | |
| 1184 | | .Array, .Vector => |zig_tag| { |
| 1196 | .Array, .Vector => |zig_ty_tag| { |
| 1185 | 1197 | switch (kind) { |
| 1186 | 1198 | .forward, .complete, .global => { |
| 1187 | | const t: Tag = switch (zig_tag) { |
| 1199 | const t: Tag = switch (zig_ty_tag) { |
| 1188 | 1200 | .Array => .array, |
| 1189 | 1201 | .Vector => .vector, |
| 1190 | 1202 | else => unreachable, |
| ... | ... | @@ -1501,120 +1513,88 @@ pub const CType = extern union { |
| 1501 | 1513 | .@"union", |
| 1502 | 1514 | .packed_struct, |
| 1503 | 1515 | .packed_union, |
| 1504 | | => switch (ty.zigTypeTag()) { |
| 1505 | | .Struct => { |
| 1506 | | const fields_len = ty.structFieldCount(); |
| 1507 | | |
| 1508 | | var c_fields_len: usize = 0; |
| 1509 | | for (0..fields_len) |field_i| { |
| 1510 | | const field_ty = ty.structFieldType(field_i); |
| 1511 | | if (ty.structFieldIsComptime(field_i) or |
| 1512 | | !field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 1513 | | c_fields_len += 1; |
| 1514 | | } |
| 1515 | | |
| 1516 | | const fields_pl = try arena.alloc(Payload.Fields.Field, c_fields_len); |
| 1517 | | var c_field_i: usize = 0; |
| 1518 | | for (0..fields_len) |field_i| { |
| 1519 | | const field_ty = ty.structFieldType(field_i); |
| 1520 | | if (ty.structFieldIsComptime(field_i) or |
| 1521 | | !field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 1522 | | |
| 1523 | | fields_pl[c_field_i] = .{ |
| 1524 | | .name = try if (ty.isSimpleTuple()) |
| 1525 | | std.fmt.allocPrintZ(arena, "f{}", .{field_i}) |
| 1526 | | else |
| 1527 | | arena.dupeZ(u8, ty.structFieldName(field_i)), |
| 1528 | | .type = store.set.typeToIndex(field_ty, target, switch (kind) { |
| 1529 | | .forward, .forward_parameter => .forward, |
| 1530 | | .complete, .parameter => .complete, |
| 1531 | | .global => .global, |
| 1532 | | .payload => unreachable, |
| 1533 | | }).?, |
| 1534 | | .alignas = Payload.Fields.AlignAs.fieldAlign(ty, field_i, target), |
| 1535 | | }; |
| 1536 | | c_field_i += 1; |
| 1537 | | } |
| 1538 | | |
| 1539 | | switch (t) { |
| 1540 | | .fwd_anon_struct => { |
| 1541 | | const anon_pl = try arena.create(Payload.Fields); |
| 1542 | | anon_pl.* = .{ .base = .{ .tag = t }, .data = fields_pl }; |
| 1543 | | return initPayload(anon_pl); |
| 1544 | | }, |
| 1545 | | |
| 1546 | | .anon_struct, |
| 1547 | | .@"struct", |
| 1548 | | .@"union", |
| 1549 | | .packed_struct, |
| 1550 | | .packed_union, |
| 1551 | | => { |
| 1552 | | const struct_pl = try arena.create(Payload.Aggregate); |
| 1553 | | struct_pl.* = .{ .base = .{ .tag = t }, .data = .{ |
| 1554 | | .fields = fields_pl, |
| 1555 | | .fwd_decl = store.set.typeToIndex(ty, target, .forward).?, |
| 1556 | | } }; |
| 1557 | | return initPayload(struct_pl); |
| 1558 | | }, |
| 1516 | => { |
| 1517 | const zig_ty_tag = ty.zigTypeTag(); |
| 1518 | const fields_len = switch (zig_ty_tag) { |
| 1519 | .Struct => ty.structFieldCount(), |
| 1520 | .Union => ty.unionFields().count(), |
| 1521 | else => unreachable, |
| 1522 | }; |
| 1559 | 1523 | |
| 1560 | | else => unreachable, |
| 1561 | | } |
| 1562 | | }, |
| 1524 | var c_fields_len: usize = 0; |
| 1525 | for (0..fields_len) |field_i| { |
| 1526 | const field_ty = ty.structFieldType(field_i); |
| 1527 | if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or |
| 1528 | !field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 1529 | c_fields_len += 1; |
| 1530 | } |
| 1563 | 1531 | |
| 1564 | | .Union => { |
| 1565 | | const union_fields = ty.unionFields(); |
| 1566 | | const fields_len = union_fields.count(); |
| 1532 | const fields_pl = try arena.alloc(Payload.Fields.Field, c_fields_len); |
| 1533 | var c_field_i: usize = 0; |
| 1534 | for (0..fields_len) |field_i| { |
| 1535 | const field_ty = ty.structFieldType(field_i); |
| 1536 | if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or |
| 1537 | !field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 1538 | |
| 1539 | defer c_field_i += 1; |
| 1540 | fields_pl[c_field_i] = .{ |
| 1541 | .name = try if (ty.isSimpleTuple()) |
| 1542 | std.fmt.allocPrintZ(arena, "f{}", .{field_i}) |
| 1543 | else |
| 1544 | arena.dupeZ(u8, switch (zig_ty_tag) { |
| 1545 | .Struct => ty.structFieldName(field_i), |
| 1546 | .Union => ty.unionFields().keys()[field_i], |
| 1547 | else => unreachable, |
| 1548 | }), |
| 1549 | .type = store.set.typeToIndex(field_ty, target, switch (kind) { |
| 1550 | .forward, .forward_parameter => .forward, |
| 1551 | .complete, .parameter, .payload => .complete, |
| 1552 | .global => .global, |
| 1553 | }).?, |
| 1554 | .alignas = Payload.Fields.AlignAs.fieldAlign(ty, field_i, target), |
| 1555 | }; |
| 1556 | } |
| 1567 | 1557 | |
| 1568 | | var c_fields_len: usize = 0; |
| 1569 | | for (0..fields_len) |field_i| { |
| 1570 | | const field_ty = ty.structFieldType(field_i); |
| 1571 | | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 1572 | | c_fields_len += 1; |
| 1573 | | } |
| 1558 | switch (t) { |
| 1559 | .fwd_anon_struct, |
| 1560 | .fwd_anon_union, |
| 1561 | => { |
| 1562 | const anon_pl = try arena.create(Payload.Fields); |
| 1563 | anon_pl.* = .{ .base = .{ .tag = t }, .data = fields_pl }; |
| 1564 | return initPayload(anon_pl); |
| 1565 | }, |
| 1574 | 1566 | |
| 1575 | | const fields_pl = try arena.alloc(Payload.Fields.Field, c_fields_len); |
| 1576 | | var field_i: usize = 0; |
| 1577 | | var c_field_i: usize = 0; |
| 1578 | | var field_it = union_fields.iterator(); |
| 1579 | | while (field_it.next()) |field| { |
| 1580 | | defer field_i += 1; |
| 1581 | | if (!field.value_ptr.ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 1582 | | |
| 1583 | | fields_pl[c_field_i] = .{ |
| 1584 | | .name = try arena.dupeZ(u8, field.key_ptr.*), |
| 1585 | | .type = store.set.typeToIndex(field.value_ptr.ty, target, switch (kind) { |
| 1586 | | .forward, .forward_parameter => unreachable, |
| 1587 | | .complete, .parameter, .payload => .complete, |
| 1588 | | .global => .global, |
| 1589 | | }).?, |
| 1590 | | .alignas = Payload.Fields.AlignAs.fieldAlign(ty, field_i, target), |
| 1591 | | }; |
| 1592 | | c_field_i += 1; |
| 1593 | | } |
| 1567 | .unnamed_struct, |
| 1568 | .unnamed_union, |
| 1569 | .packed_unnamed_struct, |
| 1570 | .packed_unnamed_union, |
| 1571 | => { |
| 1572 | const unnamed_pl = try arena.create(Payload.Unnamed); |
| 1573 | unnamed_pl.* = .{ .base = .{ .tag = t }, .data = .{ |
| 1574 | .fields = fields_pl, |
| 1575 | .owner_decl = ty.getOwnerDecl(), |
| 1576 | .id = if (ty.unionTagTypeSafety()) |_| 0 else unreachable, |
| 1577 | } }; |
| 1578 | return initPayload(unnamed_pl); |
| 1579 | }, |
| 1594 | 1580 | |
| 1595 | | switch (kind) { |
| 1596 | | .forward, .forward_parameter => unreachable, |
| 1597 | | .complete, .parameter, .global => { |
| 1598 | | const union_pl = try arena.create(Payload.Aggregate); |
| 1599 | | union_pl.* = .{ .base = .{ .tag = t }, .data = .{ |
| 1600 | | .fields = fields_pl, |
| 1601 | | .fwd_decl = store.set.typeToIndex(ty, target, .forward).?, |
| 1602 | | } }; |
| 1603 | | return initPayload(union_pl); |
| 1604 | | }, |
| 1605 | | .payload => if (ty.unionTagTypeSafety()) |_| { |
| 1606 | | const union_pl = try arena.create(Payload.Unnamed); |
| 1607 | | union_pl.* = .{ .base = .{ .tag = t }, .data = .{ |
| 1608 | | .fields = fields_pl, |
| 1609 | | .owner_decl = ty.getOwnerDecl(), |
| 1610 | | .id = 0, |
| 1611 | | } }; |
| 1612 | | return initPayload(union_pl); |
| 1613 | | } else unreachable, |
| 1614 | | } |
| 1615 | | }, |
| 1581 | .anon_struct, |
| 1582 | .anon_union, |
| 1583 | .@"struct", |
| 1584 | .@"union", |
| 1585 | .packed_struct, |
| 1586 | .packed_union, |
| 1587 | => { |
| 1588 | const struct_pl = try arena.create(Payload.Aggregate); |
| 1589 | struct_pl.* = .{ .base = .{ .tag = t }, .data = .{ |
| 1590 | .fields = fields_pl, |
| 1591 | .fwd_decl = store.set.typeToIndex(ty, target, .forward).?, |
| 1592 | } }; |
| 1593 | return initPayload(struct_pl); |
| 1594 | }, |
| 1616 | 1595 | |
| 1617 | | else => unreachable, |
| 1596 | else => unreachable, |
| 1597 | } |
| 1618 | 1598 | }, |
| 1619 | 1599 | |
| 1620 | 1600 | .function, |
| ... | ... | @@ -1710,14 +1690,19 @@ pub const CType = extern union { |
| 1710 | 1690 | ]u8 = undefined; |
| 1711 | 1691 | const c_fields = cty.cast(Payload.Fields).?.data; |
| 1712 | 1692 | |
| 1693 | const zig_ty_tag = ty.zigTypeTag(); |
| 1713 | 1694 | var c_field_i: usize = 0; |
| 1714 | | for (0..ty.structFieldCount()) |field_i| { |
| 1695 | for (0..switch (zig_ty_tag) { |
| 1696 | .Struct => ty.structFieldCount(), |
| 1697 | .Union => ty.unionFields().count(), |
| 1698 | else => unreachable, |
| 1699 | }) |field_i| { |
| 1715 | 1700 | const field_ty = ty.structFieldType(field_i); |
| 1716 | | if (ty.structFieldIsComptime(field_i) or |
| 1701 | if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or |
| 1717 | 1702 | !field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 1718 | 1703 | |
| 1704 | defer c_field_i += 1; |
| 1719 | 1705 | const c_field = &c_fields[c_field_i]; |
| 1720 | | c_field_i += 1; |
| 1721 | 1706 | |
| 1722 | 1707 | if (!self.eqlRecurse(field_ty, c_field.type, switch (self.kind) { |
| 1723 | 1708 | .forward, .forward_parameter => .forward, |
| ... | ... | @@ -1728,8 +1713,11 @@ pub const CType = extern union { |
| 1728 | 1713 | u8, |
| 1729 | 1714 | if (ty.isSimpleTuple()) |
| 1730 | 1715 | std.fmt.bufPrint(&name_buf, "f{}", .{field_i}) catch unreachable |
| 1731 | | else |
| 1732 | | ty.structFieldName(field_i), |
| 1716 | else switch (zig_ty_tag) { |
| 1717 | .Struct => ty.structFieldName(field_i), |
| 1718 | .Union => ty.unionFields().keys()[field_i], |
| 1719 | else => unreachable, |
| 1720 | }, |
| 1733 | 1721 | mem.span(c_field.name), |
| 1734 | 1722 | ) or Payload.Fields.AlignAs.fieldAlign(ty, field_i, target).@"align" != |
| 1735 | 1723 | c_field.alignas.@"align") return false; |
| ... | ... | @@ -1828,29 +1816,30 @@ pub const CType = extern union { |
| 1828 | 1816 | var name_buf: [ |
| 1829 | 1817 | std.fmt.count("f{}", .{std.math.maxInt(usize)}) |
| 1830 | 1818 | ]u8 = undefined; |
| 1819 | |
| 1820 | const zig_ty_tag = ty.zigTypeTag(); |
| 1831 | 1821 | for (0..switch (ty.zigTypeTag()) { |
| 1832 | 1822 | .Struct => ty.structFieldCount(), |
| 1833 | 1823 | .Union => ty.unionFields().count(), |
| 1834 | 1824 | else => unreachable, |
| 1835 | 1825 | }) |field_i| { |
| 1836 | 1826 | const field_ty = ty.structFieldType(field_i); |
| 1837 | | if (ty.structFieldIsComptime(field_i) or |
| 1827 | if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or |
| 1838 | 1828 | !field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 1839 | 1829 | |
| 1840 | | self.updateHasherRecurse( |
| 1841 | | hasher, |
| 1842 | | ty.structFieldType(field_i), |
| 1843 | | switch (self.kind) { |
| 1844 | | .forward, .forward_parameter => .forward, |
| 1845 | | .complete, .parameter => .complete, |
| 1846 | | .global => .global, |
| 1847 | | .payload => unreachable, |
| 1848 | | }, |
| 1849 | | ); |
| 1830 | self.updateHasherRecurse(hasher, field_ty, switch (self.kind) { |
| 1831 | .forward, .forward_parameter => .forward, |
| 1832 | .complete, .parameter => .complete, |
| 1833 | .global => .global, |
| 1834 | .payload => unreachable, |
| 1835 | }); |
| 1850 | 1836 | hasher.update(if (ty.isSimpleTuple()) |
| 1851 | 1837 | std.fmt.bufPrint(&name_buf, "f{}", .{field_i}) catch unreachable |
| 1852 | | else |
| 1853 | | ty.structFieldName(field_i)); |
| 1838 | else switch (zig_ty_tag) { |
| 1839 | .Struct => ty.structFieldName(field_i), |
| 1840 | .Union => ty.unionFields().keys()[field_i], |
| 1841 | else => unreachable, |
| 1842 | }); |
| 1854 | 1843 | autoHash( |
| 1855 | 1844 | hasher, |
| 1856 | 1845 | Payload.Fields.AlignAs.fieldAlign(ty, field_i, target).@"align", |