| ... | ... | @@ -1499,56 +1499,85 @@ pub const DeclGen = struct { |
| 1499 | 1499 | else => unreachable, |
| 1500 | 1500 | }, |
| 1501 | 1501 | .un => |un| { |
| 1502 | | if (!location.isInitializer()) { |
| 1503 | | try writer.writeByte('('); |
| 1504 | | try dg.renderType(writer, ty); |
| 1505 | | try writer.writeByte(')'); |
| 1506 | | } |
| 1507 | | |
| 1508 | 1502 | const union_obj = mod.typeToUnion(ty).?; |
| 1509 | | const field_i = mod.unionTagFieldIndex(union_obj, un.tag.toValue()).?; |
| 1510 | | const field_ty = union_obj.field_types.get(ip)[field_i].toType(); |
| 1511 | | const field_name = union_obj.field_names.get(ip)[field_i]; |
| 1512 | | if (union_obj.getLayout(ip) == .Packed) { |
| 1513 | | if (field_ty.hasRuntimeBits(mod)) { |
| 1514 | | if (field_ty.isPtrAtRuntime(mod)) { |
| 1515 | | try writer.writeByte('('); |
| 1516 | | try dg.renderType(writer, ty); |
| 1517 | | try writer.writeByte(')'); |
| 1518 | | } else if (field_ty.zigTypeTag(mod) == .Float) { |
| 1519 | | try writer.writeByte('('); |
| 1520 | | try dg.renderType(writer, ty); |
| 1521 | | try writer.writeByte(')'); |
| 1503 | if (un.tag == .none) { |
| 1504 | const backing_ty = try ty.unionBackingType(mod); |
| 1505 | switch (union_obj.getLayout(ip)) { |
| 1506 | .Packed => { |
| 1507 | if (!location.isInitializer()) { |
| 1508 | try writer.writeByte('('); |
| 1509 | try dg.renderType(writer, backing_ty); |
| 1510 | try writer.writeByte(')'); |
| 1511 | } |
| 1512 | try dg.renderValue(writer, backing_ty, un.val.toValue(), initializer_type); |
| 1513 | }, |
| 1514 | .Extern => { |
| 1515 | if (location == .StaticInitializer) { |
| 1516 | return dg.fail("TODO: C backend: implement extern union backing type rendering in static initializers", .{}); |
| 1517 | } |
| 1518 | |
| 1519 | const ptr_ty = try mod.singleConstPtrType(ty); |
| 1520 | try writer.writeAll("*(("); |
| 1521 | try dg.renderType(writer, ptr_ty); |
| 1522 | try writer.writeAll(")("); |
| 1523 | try dg.renderType(writer, backing_ty); |
| 1524 | try writer.writeAll("){"); |
| 1525 | try dg.renderValue(writer, backing_ty, un.val.toValue(), initializer_type); |
| 1526 | try writer.writeAll("})"); |
| 1527 | }, |
| 1528 | else => unreachable, |
| 1529 | } |
| 1530 | } else { |
| 1531 | if (!location.isInitializer()) { |
| 1532 | try writer.writeByte('('); |
| 1533 | try dg.renderType(writer, ty); |
| 1534 | try writer.writeByte(')'); |
| 1535 | } |
| 1536 | |
| 1537 | const field_i = mod.unionTagFieldIndex(union_obj, un.tag.toValue()).?; |
| 1538 | const field_ty = union_obj.field_types.get(ip)[field_i].toType(); |
| 1539 | const field_name = union_obj.field_names.get(ip)[field_i]; |
| 1540 | if (union_obj.getLayout(ip) == .Packed) { |
| 1541 | if (field_ty.hasRuntimeBits(mod)) { |
| 1542 | if (field_ty.isPtrAtRuntime(mod)) { |
| 1543 | try writer.writeByte('('); |
| 1544 | try dg.renderType(writer, ty); |
| 1545 | try writer.writeByte(')'); |
| 1546 | } else if (field_ty.zigTypeTag(mod) == .Float) { |
| 1547 | try writer.writeByte('('); |
| 1548 | try dg.renderType(writer, ty); |
| 1549 | try writer.writeByte(')'); |
| 1550 | } |
| 1551 | try dg.renderValue(writer, field_ty, un.val.toValue(), initializer_type); |
| 1552 | } else { |
| 1553 | try writer.writeAll("0"); |
| 1522 | 1554 | } |
| 1523 | | try dg.renderValue(writer, field_ty, un.val.toValue(), initializer_type); |
| 1524 | | } else { |
| 1525 | | try writer.writeAll("0"); |
| 1555 | return; |
| 1526 | 1556 | } |
| 1527 | | return; |
| 1528 | | } |
| 1529 | 1557 | |
| 1530 | | try writer.writeByte('{'); |
| 1531 | | if (ty.unionTagTypeSafety(mod)) |tag_ty| { |
| 1532 | | const layout = mod.getUnionLayout(union_obj); |
| 1533 | | if (layout.tag_size != 0) { |
| 1534 | | try writer.writeAll(" .tag = "); |
| 1535 | | try dg.renderValue(writer, tag_ty, un.tag.toValue(), initializer_type); |
| 1558 | try writer.writeByte('{'); |
| 1559 | if (ty.unionTagTypeSafety(mod)) |tag_ty| { |
| 1560 | const layout = mod.getUnionLayout(union_obj); |
| 1561 | if (layout.tag_size != 0) { |
| 1562 | try writer.writeAll(" .tag = "); |
| 1563 | try dg.renderValue(writer, tag_ty, un.tag.toValue(), initializer_type); |
| 1564 | } |
| 1565 | if (ty.unionHasAllZeroBitFieldTypes(mod)) return try writer.writeByte('}'); |
| 1566 | if (layout.tag_size != 0) try writer.writeByte(','); |
| 1567 | try writer.writeAll(" .payload = {"); |
| 1536 | 1568 | } |
| 1537 | | if (ty.unionHasAllZeroBitFieldTypes(mod)) return try writer.writeByte('}'); |
| 1538 | | if (layout.tag_size != 0) try writer.writeByte(','); |
| 1539 | | try writer.writeAll(" .payload = {"); |
| 1540 | | } |
| 1541 | | if (field_ty.hasRuntimeBits(mod)) { |
| 1542 | | try writer.print(" .{ } = ", .{fmtIdent(ip.stringToSlice(field_name))}); |
| 1543 | | try dg.renderValue(writer, field_ty, un.val.toValue(), initializer_type); |
| 1544 | | try writer.writeByte(' '); |
| 1545 | | } else for (union_obj.field_types.get(ip)) |this_field_ty| { |
| 1546 | | if (!this_field_ty.toType().hasRuntimeBits(mod)) continue; |
| 1547 | | try dg.renderValue(writer, this_field_ty.toType(), Value.undef, initializer_type); |
| 1548 | | break; |
| 1569 | if (field_ty.hasRuntimeBits(mod)) { |
| 1570 | try writer.print(" .{ } = ", .{fmtIdent(ip.stringToSlice(field_name))}); |
| 1571 | try dg.renderValue(writer, field_ty, un.val.toValue(), initializer_type); |
| 1572 | try writer.writeByte(' '); |
| 1573 | } else for (union_obj.field_types.get(ip)) |this_field_ty| { |
| 1574 | if (!this_field_ty.toType().hasRuntimeBits(mod)) continue; |
| 1575 | try dg.renderValue(writer, this_field_ty.toType(), Value.undef, initializer_type); |
| 1576 | break; |
| 1577 | } |
| 1578 | if (ty.unionTagTypeSafety(mod)) |_| try writer.writeByte('}'); |
| 1579 | try writer.writeByte('}'); |
| 1549 | 1580 | } |
| 1550 | | if (ty.unionTagTypeSafety(mod)) |_| try writer.writeByte('}'); |
| 1551 | | try writer.writeByte('}'); |
| 1552 | 1581 | }, |
| 1553 | 1582 | } |
| 1554 | 1583 | } |