| ... | ... | @@ -1053,9 +1053,46 @@ pub const DeclGen = struct { |
| 1053 | 1053 | return Result{ .appended = {} }; |
| 1054 | 1054 | }, |
| 1055 | 1055 | .Union => { |
| 1056 | | // TODO: Implement Union declarations |
| 1057 | | try writer.writeByteNTimes(0xaa, @intCast(usize, ty.abiSize(self.target()))); |
| 1058 | | return Result{ .appended = {} }; |
| 1056 | const union_val = val.castTag(.@"union").?.data; |
| 1057 | const layout = ty.unionGetLayout(self.target()); |
| 1058 | |
| 1059 | if (layout.payload_size == 0) { |
| 1060 | return self.genTypedValue(ty.unionTagType().?, union_val.tag, writer); |
| 1061 | } |
| 1062 | |
| 1063 | // Check if we should store the tag first, in which case, do so now: |
| 1064 | if (layout.tag_align >= layout.payload_align) { |
| 1065 | switch (try self.genTypedValue(ty.unionTagType().?, union_val.tag, writer)) { |
| 1066 | .appended => {}, |
| 1067 | .externally_managed => |payload| try writer.writeAll(payload), |
| 1068 | } |
| 1069 | } |
| 1070 | |
| 1071 | const union_ty = ty.cast(Type.Payload.Union).?.data; |
| 1072 | const field_index = union_ty.tag_ty.enumTagFieldIndex(union_val.tag).?; |
| 1073 | assert(union_ty.haveFieldTypes()); |
| 1074 | const field_ty = union_ty.fields.values()[field_index].ty; |
| 1075 | if (!field_ty.hasCodeGenBits()) { |
| 1076 | try writer.writeByteNTimes(0xaa, layout.payload_size); |
| 1077 | } else { |
| 1078 | switch (try self.genTypedValue(field_ty, union_val.val, writer)) { |
| 1079 | .appended => {}, |
| 1080 | .externally_managed => |payload| try writer.writeAll(payload), |
| 1081 | } |
| 1082 | |
| 1083 | // Unions have the size of the largest field, so we must pad |
| 1084 | // whenever the active field has a smaller size. |
| 1085 | const diff = layout.payload_size - field_ty.abiSize(self.target()); |
| 1086 | if (diff > 0) { |
| 1087 | try writer.writeByteNTimes(0xaa, diff); |
| 1088 | } |
| 1089 | } |
| 1090 | |
| 1091 | if (layout.tag_size == 0) { |
| 1092 | return Result{ .appended = {} }; |
| 1093 | } |
| 1094 | |
| 1095 | return self.genTypedValue(union_ty.tag_ty, union_val.tag, writer); |
| 1059 | 1096 | }, |
| 1060 | 1097 | .Pointer => switch (val.tag()) { |
| 1061 | 1098 | .variable => { |