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