| ... | @@ -1053,9 +1053,46 @@ pub const DeclGen = struct { | ... | @@ -1053,9 +1053,46 @@ pub const DeclGen = struct { |
| 1053 | return Result{ .appended = {} }; | 1053 | return Result{ .appended = {} }; |
| 1054 | }, | 1054 | }, |
| 1055 | .Union => { | 1055 | .Union => { |
| 1056 | // TODO: Implement Union declarations | 1056 | const union_val = val.castTag(.@"union").?.data; |
| 1057 | try writer.writeByteNTimes(0xaa, @intCast(usize, ty.abiSize(self.target()))); | 1057 | const layout = ty.unionGetLayout(self.target()); |
| 1058 | return Result{ .appended = {} }; | 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 | .Pointer => switch (val.tag()) { | 1097 | .Pointer => switch (val.tag()) { |
| 1061 | .variable => { | 1098 | .variable => { |