authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-12 16:00:29+03:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-13 08:12:17-07:00
log75eaf15740bc42167592f3bdd7205236828191c7
tree49edad088171ff45d6265ad88147c89f1a90298b
parentcb06d62603c764a91aeb9bcedc0b9472d746f9e5

stage2: add optional types


1 files changed, 155 insertions(+), 26 deletions(-)

src-self-hosted/type.zig+155-26
......@@ -70,6 +70,11 @@ pub const Type = extern union {
7070 .single_mut_pointer => return .Pointer,
7171 .single_const_pointer_to_comptime_int => return .Pointer,
7272 .const_slice_u8 => return .Pointer,
73
74 .optional,
75 .optional_single_const_pointer,
76 .optional_single_mut_pointer,
77 => return .Optional,
7378 }
7479 }
7580
......@@ -179,9 +184,13 @@ pub const Type = extern union {
179184 }
180185 return true;
181186 },
187 .Optional => {
188 if (a.tag() != b.tag())
189 return false;
190 return a.elemType().eql(b.elemType());
191 },
182192 .Float,
183193 .Struct,
184 .Optional,
185194 .ErrorUnion,
186195 .ErrorSet,
187196 .Enum,
......@@ -241,9 +250,11 @@ pub const Type = extern union {
241250 std.hash.autoHash(&hasher, self.fnParamType(i).hash());
242251 }
243252 },
253 .Optional => {
254 std.hash.autoHash(&hasher, self.elemType().hash());
255 },
244256 .Float,
245257 .Struct,
246 .Optional,
247258 .ErrorUnion,
248259 .ErrorSet,
249260 .Enum,
......@@ -317,24 +328,8 @@ pub const Type = extern union {
317328 };
318329 return Type{ .ptr_otherwise = &new_payload.base };
319330 },
320 .single_const_pointer => {
321 const payload = @fieldParentPtr(Payload.SingleConstPointer, "base", self.ptr_otherwise);
322 const new_payload = try allocator.create(Payload.SingleConstPointer);
323 new_payload.* = .{
324 .base = payload.base,
325 .pointee_type = try payload.pointee_type.copy(allocator),
326 };
327 return Type{ .ptr_otherwise = &new_payload.base };
328 },
329 .single_mut_pointer => {
330 const payload = @fieldParentPtr(Payload.SingleMutPointer, "base", self.ptr_otherwise);
331 const new_payload = try allocator.create(Payload.SingleMutPointer);
332 new_payload.* = .{
333 .base = payload.base,
334 .pointee_type = try payload.pointee_type.copy(allocator),
335 };
336 return Type{ .ptr_otherwise = &new_payload.base };
337 },
331 .single_const_pointer => return self.copyPayloadSingleField(allocator, Payload.SingleConstPointer, "pointee_type"),
332 .single_mut_pointer => return self.copyPayloadSingleField(allocator, Payload.SingleMutPointer, "pointee_type"),
338333 .int_signed => return self.copyPayloadShallow(allocator, Payload.IntSigned),
339334 .int_unsigned => return self.copyPayloadShallow(allocator, Payload.IntUnsigned),
340335 .function => {
......@@ -352,6 +347,9 @@ pub const Type = extern union {
352347 };
353348 return Type{ .ptr_otherwise = &new_payload.base };
354349 },
350 .optional => return self.copyPayloadSingleField(allocator, Payload.Optional, "child_type"),
351 .optional_single_mut_pointer => return self.copyPayloadSingleField(allocator, Payload.OptionalSingleMutPointer, "pointee_type"),
352 .optional_single_const_pointer => return self.copyPayloadSingleField(allocator, Payload.OptionalSingleConstPointer, "pointee_type"),
355353 }
356354 }
357355
......@@ -362,6 +360,14 @@ pub const Type = extern union {
362360 return Type{ .ptr_otherwise = &new_payload.base };
363361 }
364362
363 fn copyPayloadSingleField(self: Type, allocator: *Allocator, comptime T: type, comptime field_name: []const u8) error{OutOfMemory}!Type {
364 const payload = @fieldParentPtr(T, "base", self.ptr_otherwise);
365 const new_payload = try allocator.create(T);
366 new_payload.base = payload.base;
367 @field(new_payload, field_name) = try @field(payload, field_name).copy(allocator);
368 return Type{ .ptr_otherwise = &new_payload.base };
369 }
370
365371 pub fn format(
366372 self: Type,
367373 comptime fmt: []const u8,
......@@ -456,6 +462,24 @@ pub const Type = extern union {
456462 const payload = @fieldParentPtr(Payload.IntUnsigned, "base", ty.ptr_otherwise);
457463 return out_stream.print("u{}", .{payload.bits});
458464 },
465 .optional => {
466 const payload = @fieldParentPtr(Payload.Optional, "base", ty.ptr_otherwise);
467 try out_stream.writeByte('?');
468 ty = payload.child_type;
469 continue;
470 },
471 .optional_single_const_pointer => {
472 const payload = @fieldParentPtr(Payload.OptionalSingleConstPointer, "base", ty.ptr_otherwise);
473 try out_stream.writeAll("?*const ");
474 ty = payload.pointee_type;
475 continue;
476 },
477 .optional_single_mut_pointer => {
478 const payload = @fieldParentPtr(Payload.OptionalSingleMutPointer, "base", ty.ptr_otherwise);
479 try out_stream.writeAll("?*");
480 ty = payload.pointee_type;
481 continue;
482 },
459483 }
460484 unreachable;
461485 }
......@@ -545,11 +569,15 @@ pub const Type = extern union {
545569 .single_const_pointer_to_comptime_int,
546570 .const_slice_u8,
547571 .array_u8_sentinel_0,
548 .array, // TODO check for zero bits
549 .single_const_pointer,
550 .single_mut_pointer,
551 .int_signed, // TODO check for zero bits
552 .int_unsigned, // TODO check for zero bits
572 // TODO lazy types
573 .array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0,
574 .single_const_pointer => self.elemType().hasCodeGenBits(),
575 .single_mut_pointer => self.elemType().hasCodeGenBits(),
576 .int_signed => self.cast(Payload.IntSigned).?.bits == 0,
577 .int_unsigned => self.cast(Payload.IntUnsigned).?.bits == 0,
578 .optional,
579 .optional_single_mut_pointer,
580 .optional_single_const_pointer,
553581 => true,
554582
555583 .c_void,
......@@ -597,6 +625,8 @@ pub const Type = extern union {
597625 .const_slice_u8,
598626 .single_const_pointer,
599627 .single_mut_pointer,
628 .optional_single_const_pointer,
629 .optional_single_mut_pointer,
600630 => return @divExact(target.cpu.arch.ptrBitWidth(), 8),
601631
602632 .c_short => return @divExact(CType.short.sizeInBits(target), 8),
......@@ -629,6 +659,12 @@ pub const Type = extern union {
629659 return std.math.ceilPowerOfTwoPromote(u16, (bits + 7) / 8);
630660 },
631661
662 .optional => {
663 const child_type = self.cast(Payload.Optional).?.child_type;
664 if (!child_type.hasCodeGenBits()) return 1;
665 return child_type.abiAlignment(target);
666 },
667
632668 .c_void,
633669 .void,
634670 .type,
......@@ -679,6 +715,8 @@ pub const Type = extern union {
679715 .const_slice_u8,
680716 .single_const_pointer,
681717 .single_mut_pointer,
718 .optional_single_const_pointer,
719 .optional_single_mut_pointer,
682720 => return @divExact(target.cpu.arch.ptrBitWidth(), 8),
683721
684722 .c_short => return @divExact(CType.short.sizeInBits(target), 8),
......@@ -708,6 +746,16 @@ pub const Type = extern union {
708746
709747 return std.math.ceilPowerOfTwoPromote(u16, (bits + 7) / 8);
710748 },
749
750 .optional => {
751 const child_type = self.cast(Payload.Optional).?.child_type;
752 if (!child_type.hasCodeGenBits()) return 1;
753 // Optional types are represented as a struct with the child type as the first
754 // field and a boolean as the second. Since the child type's abi alignment is
755 // guaranteed to be >= that of bool's (1 byte) the added size is exactly equal
756 // to the child type's ABI alignment.
757 return child_type.abiAlignment(target) + child_type.abiSize(target);
758 },
711759 };
712760 }
713761
......@@ -756,6 +804,9 @@ pub const Type = extern union {
756804 .function,
757805 .int_unsigned,
758806 .int_signed,
807 .optional,
808 .optional_single_mut_pointer,
809 .optional_single_const_pointer,
759810 => false,
760811
761812 .single_const_pointer,
......@@ -812,6 +863,9 @@ pub const Type = extern union {
812863 .function,
813864 .int_unsigned,
814865 .int_signed,
866 .optional,
867 .optional_single_mut_pointer,
868 .optional_single_const_pointer,
815869 => false,
816870
817871 .const_slice_u8 => true,
......@@ -863,6 +917,9 @@ pub const Type = extern union {
863917 .int_unsigned,
864918 .int_signed,
865919 .single_mut_pointer,
920 .optional,
921 .optional_single_mut_pointer,
922 .optional_single_const_pointer,
866923 => false,
867924
868925 .single_const_pointer,
......@@ -920,11 +977,14 @@ pub const Type = extern union {
920977 .single_const_pointer,
921978 .single_const_pointer_to_comptime_int,
922979 .const_slice_u8,
980 .optional,
981 .optional_single_mut_pointer,
982 .optional_single_const_pointer,
923983 => false,
924984 };
925985 }
926986
927 /// Asserts the type is a pointer or array type.
987 /// Asserts the type is a pointer, optional or array type.
928988 pub fn elemType(self: Type) Type {
929989 return switch (self.tag()) {
930990 .u8,
......@@ -974,6 +1034,9 @@ pub const Type = extern union {
9741034 .single_mut_pointer => self.cast(Payload.SingleMutPointer).?.pointee_type,
9751035 .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8),
9761036 .single_const_pointer_to_comptime_int => Type.initTag(.comptime_int),
1037 .optional => self.cast(Payload.Optional).?.child_type,
1038 .optional_single_mut_pointer => self.cast(Payload.OptionalSingleMutPointer).?.pointee_type,
1039 .optional_single_const_pointer => self.cast(Payload.OptionalSingleConstPointer).?.pointee_type,
9771040 };
9781041 }
9791042
......@@ -1024,6 +1087,9 @@ pub const Type = extern union {
10241087 .const_slice_u8,
10251088 .int_unsigned,
10261089 .int_signed,
1090 .optional,
1091 .optional_single_mut_pointer,
1092 .optional_single_const_pointer,
10271093 => unreachable,
10281094
10291095 .array => self.cast(Payload.Array).?.len,
......@@ -1078,6 +1144,9 @@ pub const Type = extern union {
10781144 .const_slice_u8,
10791145 .int_unsigned,
10801146 .int_signed,
1147 .optional,
1148 .optional_single_mut_pointer,
1149 .optional_single_const_pointer,
10811150 => unreachable,
10821151
10831152 .array => return null,
......@@ -1129,6 +1198,9 @@ pub const Type = extern union {
11291198 .u16,
11301199 .u32,
11311200 .u64,
1201 .optional,
1202 .optional_single_mut_pointer,
1203 .optional_single_const_pointer,
11321204 => false,
11331205
11341206 .int_signed,
......@@ -1184,6 +1256,9 @@ pub const Type = extern union {
11841256 .i16,
11851257 .i32,
11861258 .i64,
1259 .optional,
1260 .optional_single_mut_pointer,
1261 .optional_single_const_pointer,
11871262 => false,
11881263
11891264 .int_unsigned,
......@@ -1229,6 +1304,9 @@ pub const Type = extern union {
12291304 .single_const_pointer_to_comptime_int,
12301305 .array_u8_sentinel_0,
12311306 .const_slice_u8,
1307 .optional,
1308 .optional_single_mut_pointer,
1309 .optional_single_const_pointer,
12321310 => unreachable,
12331311
12341312 .int_unsigned => .{ .signed = false, .bits = self.cast(Payload.IntUnsigned).?.bits },
......@@ -1292,6 +1370,9 @@ pub const Type = extern union {
12921370 .i32,
12931371 .u64,
12941372 .i64,
1373 .optional,
1374 .optional_single_mut_pointer,
1375 .optional_single_const_pointer,
12951376 => false,
12961377
12971378 .usize,
......@@ -1384,6 +1465,9 @@ pub const Type = extern union {
13841465 .c_ulonglong,
13851466 .int_unsigned,
13861467 .int_signed,
1468 .optional,
1469 .optional_single_mut_pointer,
1470 .optional_single_const_pointer,
13871471 => unreachable,
13881472 };
13891473 }
......@@ -1442,6 +1526,9 @@ pub const Type = extern union {
14421526 .c_ulonglong,
14431527 .int_unsigned,
14441528 .int_signed,
1529 .optional,
1530 .optional_single_mut_pointer,
1531 .optional_single_const_pointer,
14451532 => unreachable,
14461533 }
14471534 }
......@@ -1499,6 +1586,9 @@ pub const Type = extern union {
14991586 .c_ulonglong,
15001587 .int_unsigned,
15011588 .int_signed,
1589 .optional,
1590 .optional_single_mut_pointer,
1591 .optional_single_const_pointer,
15021592 => unreachable,
15031593 }
15041594 }
......@@ -1556,6 +1646,9 @@ pub const Type = extern union {
15561646 .c_ulonglong,
15571647 .int_unsigned,
15581648 .int_signed,
1649 .optional,
1650 .optional_single_mut_pointer,
1651 .optional_single_const_pointer,
15591652 => unreachable,
15601653 };
15611654 }
......@@ -1610,6 +1703,9 @@ pub const Type = extern union {
16101703 .c_ulonglong,
16111704 .int_unsigned,
16121705 .int_signed,
1706 .optional,
1707 .optional_single_mut_pointer,
1708 .optional_single_const_pointer,
16131709 => unreachable,
16141710 };
16151711 }
......@@ -1664,6 +1760,9 @@ pub const Type = extern union {
16641760 .c_ulonglong,
16651761 .int_unsigned,
16661762 .int_signed,
1763 .optional,
1764 .optional_single_mut_pointer,
1765 .optional_single_const_pointer,
16671766 => unreachable,
16681767 };
16691768 }
......@@ -1718,6 +1817,9 @@ pub const Type = extern union {
17181817 .single_const_pointer_to_comptime_int,
17191818 .array_u8_sentinel_0,
17201819 .const_slice_u8,
1820 .optional,
1821 .optional_single_mut_pointer,
1822 .optional_single_const_pointer,
17211823 => false,
17221824 };
17231825 }
......@@ -1762,6 +1864,9 @@ pub const Type = extern union {
17621864 .array_u8_sentinel_0,
17631865 .const_slice_u8,
17641866 .c_void,
1867 .optional,
1868 .optional_single_mut_pointer,
1869 .optional_single_const_pointer,
17651870 => return null,
17661871
17671872 .void => return Value.initTag(.void_value),
......@@ -1851,6 +1956,9 @@ pub const Type = extern union {
18511956 .array,
18521957 .single_const_pointer,
18531958 .single_mut_pointer,
1959 .optional,
1960 .optional_single_mut_pointer,
1961 .optional_single_const_pointer,
18541962 => return false,
18551963 };
18561964 }
......@@ -1911,6 +2019,9 @@ pub const Type = extern union {
19112019 int_signed,
19122020 int_unsigned,
19132021 function,
2022 optional,
2023 optional_single_mut_pointer,
2024 optional_single_const_pointer,
19142025
19152026 pub const last_no_payload_tag = Tag.const_slice_u8;
19162027 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
......@@ -1963,6 +2074,24 @@ pub const Type = extern union {
19632074 return_type: Type,
19642075 cc: std.builtin.CallingConvention,
19652076 };
2077
2078 pub const Optional = struct {
2079 base: Payload = Payload{ .tag = .optional },
2080
2081 child_type: Type,
2082 };
2083
2084 pub const OptionalSingleConstPointer = struct {
2085 base: Payload = Payload{ .tag = .optional_single_const_pointer },
2086
2087 pointee_type: Type,
2088 };
2089
2090 pub const OptionalSingleMutPointer = struct {
2091 base: Payload = Payload{ .tag = .optional_single_mut_pointer },
2092
2093 pointee_type: Type,
2094 };
19662095 };
19672096};
19682097