authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-20 13:52:18+03:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-20 16:42:48-07:00
log95682484503f031efefb2c085cdd4d0b64cf8795
treee6df9cf657f5e35839d120a0c6ac7709d580c55d
parentebfe723f3cdbb40d2f2280e223b710418abde777

stage2: complex pointer types


5 files changed, 202 insertions(+), 12 deletions(-)

src-self-hosted/Module.zig+33-1
......@@ -3153,7 +3153,7 @@ pub fn simplePtrType(self: *Module, scope: *Scope, src: usize, elem_ty: Type, mu
31533153 type_payload.* = .{
31543154 .base = .{
31553155 .tag = switch (size) {
3156 .One => if (mutable) .single_mut_pointer else T.many_const_pointer,
3156 .One => if (mutable) T.single_mut_pointer else T.single_const_pointer,
31573157 .Many => if (mutable) T.many_mut_pointer else T.many_const_pointer,
31583158 .C => if (mutable) T.c_mut_pointer else T.c_const_pointer,
31593159 else => unreachable,
......@@ -3164,6 +3164,38 @@ pub fn simplePtrType(self: *Module, scope: *Scope, src: usize, elem_ty: Type, mu
31643164 return Type.initPayload(&type_payload.base);
31653165}
31663166
3167pub fn ptrType(
3168 self: *Module,
3169 scope: *Scope,
3170 src: usize,
3171 elem_ty: Type,
3172 sentinel: ?Value,
3173 @"align": u32,
3174 bit_offset: u16,
3175 host_size: u16,
3176 mutable: bool,
3177 @"allowzero": bool,
3178 @"volatile": bool,
3179 size: std.builtin.TypeInfo.Pointer.Size,
3180) Allocator.Error!Type {
3181 assert(host_size == 0 or bit_offset < host_size * 8);
3182
3183 // TODO check if type can be represented by simplePtrType
3184 const type_payload = try scope.arena().create(Type.Payload.Pointer);
3185 type_payload.* = .{
3186 .pointee_type = elem_ty,
3187 .sentinel = sentinel,
3188 .@"align" = @"align",
3189 .bit_offset = bit_offset,
3190 .host_size = host_size,
3191 .@"allowzero" = @"allowzero",
3192 .mutable = mutable,
3193 .@"volatile" = @"volatile",
3194 .size = size,
3195 };
3196 return Type.initPayload(&type_payload.base);
3197}
3198
31673199pub fn optionalType(self: *Module, scope: *Scope, child_type: Type) Allocator.Error!Type {
31683200 return Type.initPayload(switch (child_type.tag()) {
31693201 .single_const_pointer => blk: {
src-self-hosted/astgen.zig+2-3
......@@ -582,8 +582,7 @@ fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir
582582 // TODO stage1 type inference bug
583583 .LBracket => @as(std.builtin.TypeInfo.Pointer.Size, switch (tree.token_ids[node.op_token + 2]) {
584584 .Identifier => .C,
585 .RBracket => .Many,
586 else => unreachable,
585 else => .Many,
587586 }),
588587 else => unreachable,
589588 };
......@@ -616,7 +615,7 @@ fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir
616615 kw_args.align_bit_end = try expr(mod, scope, .none, bit_range.end);
617616 }
618617 }
619 kw_args.@"const" = node.ptr_info.const_token != null;
618 kw_args.mutable = node.ptr_info.const_token == null;
620619 kw_args.@"volatile" = node.ptr_info.volatile_token != null;
621620 if (node.ptr_info.sentinel) |some| {
622621 kw_args.sentinel = try expr(mod, scope, .none, some);
src-self-hosted/type.zig+120-6
......@@ -74,6 +74,7 @@ pub const Type = extern union {
7474 .many_mut_pointer,
7575 .c_const_pointer,
7676 .c_mut_pointer,
77 .pointer,
7778 => return .Pointer,
7879
7980 .optional,
......@@ -390,6 +391,25 @@ pub const Type = extern union {
390391 .optional_single_mut_pointer,
391392 .optional_single_const_pointer,
392393 => return self.copyPayloadSingleField(allocator, Payload.PointerSimple, "pointee_type"),
394
395 .pointer => {
396 const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise);
397 const new_payload = try allocator.create(Payload.Pointer);
398 new_payload.* = .{
399 .base = payload.base,
400
401 .pointee_type = try payload.pointee_type.copy(allocator),
402 .sentinel = if (payload.sentinel) |some| try some.copy(allocator) else null,
403 .@"align" = payload.@"align",
404 .bit_offset = payload.bit_offset,
405 .host_size = payload.host_size,
406 .@"allowzero" = payload.@"allowzero",
407 .mutable = payload.mutable,
408 .@"volatile" = payload.@"volatile",
409 .size = payload.size,
410 };
411 return Type{ .ptr_otherwise = &new_payload.base };
412 },
393413 }
394414 }
395415
......@@ -556,6 +576,34 @@ pub const Type = extern union {
556576 ty = payload.pointee_type;
557577 continue;
558578 },
579
580 .pointer => {
581 const payload = @fieldParentPtr(Payload.Pointer, "base", ty.ptr_otherwise);
582 if (payload.sentinel) |some| switch (payload.size) {
583 .One, .C => unreachable,
584 .Many => try out_stream.writeAll("[*:{}]"),
585 .Slice => try out_stream.writeAll("[:{}]"),
586 } else switch (payload.size) {
587 .One => try out_stream.writeAll("*"),
588 .Many => try out_stream.writeAll("[*]"),
589 .C => try out_stream.writeAll("[*c]"),
590 .Slice => try out_stream.writeAll("[]"),
591 }
592 if (payload.@"align" != 0) {
593 try out_stream.print("align({}", .{payload.@"align"});
594
595 if (payload.bit_offset != 0) {
596 try out_stream.print(":{}:{}", .{ payload.bit_offset, payload.host_size });
597 }
598 try out_stream.writeAll(") ");
599 }
600 if (!payload.mutable) try out_stream.writeAll("const ");
601 if (payload.@"volatile") try out_stream.writeAll("volatile ");
602 if (payload.@"allowzero") try out_stream.writeAll("allowzero ");
603
604 ty = payload.pointee_type;
605 continue;
606 },
559607 }
560608 unreachable;
561609 }
......@@ -660,6 +708,7 @@ pub const Type = extern union {
660708 .many_mut_pointer => self.elemType().hasCodeGenBits(),
661709 .c_const_pointer => self.elemType().hasCodeGenBits(),
662710 .c_mut_pointer => self.elemType().hasCodeGenBits(),
711 .pointer => self.elemType().hasCodeGenBits(),
663712 .int_signed => self.cast(Payload.IntSigned).?.bits == 0,
664713 .int_unsigned => self.cast(Payload.IntUnsigned).?.bits == 0,
665714
......@@ -718,6 +767,13 @@ pub const Type = extern union {
718767 .optional_single_mut_pointer,
719768 => return @divExact(target.cpu.arch.ptrBitWidth(), 8),
720769
770 .pointer => {
771 const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise);
772
773 if (payload.@"align" != 0) return payload.@"align";
774 return @divExact(target.cpu.arch.ptrBitWidth(), 8);
775 },
776
721777 .c_short => return @divExact(CType.short.sizeInBits(target), 8),
722778 .c_ushort => return @divExact(CType.ushort.sizeInBits(target), 8),
723779 .c_int => return @divExact(CType.int.sizeInBits(target), 8),
......@@ -789,6 +845,7 @@ pub const Type = extern union {
789845 .@"null" => unreachable,
790846 .@"undefined" => unreachable,
791847 .enum_literal => unreachable,
848 .single_const_pointer_to_comptime_int => unreachable,
792849
793850 .u8,
794851 .i8,
......@@ -812,18 +869,28 @@ pub const Type = extern union {
812869 .i64, .u64 => return 8,
813870
814871 .isize,
815 .usize,
816 .single_const_pointer_to_comptime_int,
817 .const_slice_u8,
872 .usize
873 => return @divExact(target.cpu.arch.ptrBitWidth(), 8),
874 .const_slice_u8 => return @divExact(target.cpu.arch.ptrBitWidth(), 8) * 2,
875
876 .optional_single_const_pointer,
877 .optional_single_mut_pointer,
878 => {
879 if (self.elemType().hasCodeGenBits()) return 1;
880 return @divExact(target.cpu.arch.ptrBitWidth(), 8);
881 },
882
818883 .single_const_pointer,
819884 .single_mut_pointer,
820885 .many_const_pointer,
821886 .many_mut_pointer,
822887 .c_const_pointer,
823888 .c_mut_pointer,
824 .optional_single_const_pointer,
825 .optional_single_mut_pointer,
826 => return @divExact(target.cpu.arch.ptrBitWidth(), 8),
889 .pointer,
890 => {
891 if (self.elemType().hasCodeGenBits()) return 0;
892 return @divExact(target.cpu.arch.ptrBitWidth(), 8);
893 },
827894
828895 .c_short => return @divExact(CType.short.sizeInBits(target), 8),
829896 .c_ushort => return @divExact(CType.ushort.sizeInBits(target), 8),
......@@ -931,6 +998,8 @@ pub const Type = extern union {
931998 .single_mut_pointer,
932999 .single_const_pointer_to_comptime_int,
9331000 => true,
1001
1002 .pointer => self.cast(Payload.Pointer).?.size == .One,
9341003 };
9351004 }
9361005
......@@ -994,6 +1063,8 @@ pub const Type = extern union {
9941063 => false,
9951064
9961065 .const_slice_u8 => true,
1066
1067 .pointer => self.cast(Payload.Pointer).?.size == .Slice,
9971068 };
9981069 }
9991070
......@@ -1058,6 +1129,8 @@ pub const Type = extern union {
10581129 .single_const_pointer_to_comptime_int,
10591130 .const_slice_u8,
10601131 => true,
1132
1133 .pointer => !self.cast(Payload.Pointer).?.mutable,
10611134 };
10621135 }
10631136
......@@ -1120,6 +1193,11 @@ pub const Type = extern union {
11201193 .optional_single_const_pointer,
11211194 .enum_literal,
11221195 => false,
1196
1197 .pointer => {
1198 const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise);
1199 return payload.@"volatile";
1200 },
11231201 };
11241202 }
11251203
......@@ -1237,6 +1315,7 @@ pub const Type = extern union {
12371315 .c_mut_pointer => self.castPointer().?.pointee_type,
12381316 .array_u8, .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8),
12391317 .single_const_pointer_to_comptime_int => Type.initTag(.comptime_int),
1318 .pointer => self.cast(Payload.Pointer).?.pointee_type,
12401319 };
12411320 }
12421321
......@@ -1325,6 +1404,7 @@ pub const Type = extern union {
13251404 .fn_naked_noreturn_no_args,
13261405 .fn_ccc_void_no_args,
13271406 .function,
1407 .pointer,
13281408 .single_const_pointer,
13291409 .single_mut_pointer,
13301410 .many_const_pointer,
......@@ -1389,6 +1469,7 @@ pub const Type = extern union {
13891469 .fn_naked_noreturn_no_args,
13901470 .fn_ccc_void_no_args,
13911471 .function,
1472 .pointer,
13921473 .single_const_pointer,
13931474 .single_mut_pointer,
13941475 .many_const_pointer,
......@@ -1443,6 +1524,7 @@ pub const Type = extern union {
14431524 .array_sentinel,
14441525 .array_u8,
14451526 .array_u8_sentinel_0,
1527 .pointer,
14461528 .single_const_pointer,
14471529 .single_mut_pointer,
14481530 .many_const_pointer,
......@@ -1508,6 +1590,7 @@ pub const Type = extern union {
15081590 .array_sentinel,
15091591 .array_u8,
15101592 .array_u8_sentinel_0,
1593 .pointer,
15111594 .single_const_pointer,
15121595 .single_mut_pointer,
15131596 .many_const_pointer,
......@@ -1573,6 +1656,7 @@ pub const Type = extern union {
15731656 .array_sentinel,
15741657 .array_u8,
15751658 .array_u8_sentinel_0,
1659 .pointer,
15761660 .single_const_pointer,
15771661 .single_mut_pointer,
15781662 .many_const_pointer,
......@@ -1636,6 +1720,7 @@ pub const Type = extern union {
16361720 .array_sentinel,
16371721 .array_u8,
16381722 .array_u8_sentinel_0,
1723 .pointer,
16391724 .single_const_pointer,
16401725 .single_mut_pointer,
16411726 .many_const_pointer,
......@@ -1728,6 +1813,7 @@ pub const Type = extern union {
17281813 .array_sentinel,
17291814 .array_u8,
17301815 .array_u8_sentinel_0,
1816 .pointer,
17311817 .single_const_pointer,
17321818 .single_mut_pointer,
17331819 .many_const_pointer,
......@@ -1796,6 +1882,7 @@ pub const Type = extern union {
17961882 .array_sentinel,
17971883 .array_u8,
17981884 .array_u8_sentinel_0,
1885 .pointer,
17991886 .single_const_pointer,
18001887 .single_mut_pointer,
18011888 .many_const_pointer,
......@@ -1863,6 +1950,7 @@ pub const Type = extern union {
18631950 .array_sentinel,
18641951 .array_u8,
18651952 .array_u8_sentinel_0,
1953 .pointer,
18661954 .single_const_pointer,
18671955 .single_mut_pointer,
18681956 .many_const_pointer,
......@@ -1930,6 +2018,7 @@ pub const Type = extern union {
19302018 .array_sentinel,
19312019 .array_u8,
19322020 .array_u8_sentinel_0,
2021 .pointer,
19332022 .single_const_pointer,
19342023 .single_mut_pointer,
19352024 .many_const_pointer,
......@@ -1994,6 +2083,7 @@ pub const Type = extern union {
19942083 .array_sentinel,
19952084 .array_u8,
19962085 .array_u8_sentinel_0,
2086 .pointer,
19972087 .single_const_pointer,
19982088 .single_mut_pointer,
19992089 .many_const_pointer,
......@@ -2058,6 +2148,7 @@ pub const Type = extern union {
20582148 .array_sentinel,
20592149 .array_u8,
20602150 .array_u8_sentinel_0,
2151 .pointer,
20612152 .single_const_pointer,
20622153 .single_mut_pointer,
20632154 .many_const_pointer,
......@@ -2142,6 +2233,7 @@ pub const Type = extern union {
21422233 .array_sentinel,
21432234 .array_u8,
21442235 .array_u8_sentinel_0,
2236 .pointer,
21452237 .single_const_pointer,
21462238 .single_mut_pointer,
21472239 .many_const_pointer,
......@@ -2241,6 +2333,10 @@ pub const Type = extern union {
22412333 ty = ptr.pointee_type;
22422334 continue;
22432335 },
2336 .pointer => {
2337 ty = ty.cast(Payload.Pointer).?.pointee_type;
2338 continue;
2339 },
22442340 };
22452341 }
22462342
......@@ -2305,6 +2401,8 @@ pub const Type = extern union {
23052401 .c_const_pointer,
23062402 .c_mut_pointer,
23072403 => return true,
2404
2405 .pointer => self.cast(Payload.Pointer).?.size == .C,
23082406 };
23092407 }
23102408
......@@ -2362,6 +2460,7 @@ pub const Type = extern union {
23622460 array_u8_sentinel_0,
23632461 array,
23642462 array_sentinel,
2463 pointer,
23652464 single_const_pointer,
23662465 single_mut_pointer,
23672466 many_const_pointer,
......@@ -2440,6 +2539,21 @@ pub const Type = extern union {
24402539
24412540 child_type: Type,
24422541 };
2542
2543 pub const Pointer = struct {
2544 base: Payload = .{ .tag = .pointer },
2545
2546 pointee_type: Type,
2547 sentinel: ?Value,
2548 /// If zero use pointee_type.AbiAlign()
2549 @"align": u32,
2550 bit_offset: u16,
2551 host_size: u16,
2552 @"allowzero": bool,
2553 mutable: bool,
2554 @"volatile": bool,
2555 size: std.builtin.TypeInfo.Pointer.Size,
2556 };
24432557 };
24442558};
24452559
src-self-hosted/zir.zig+1-1
......@@ -872,7 +872,7 @@ pub const Inst = struct {
872872 @"align": ?*Inst = null,
873873 align_bit_start: ?*Inst = null,
874874 align_bit_end: ?*Inst = null,
875 @"const": bool = true,
875 mutable: bool = true,
876876 @"volatile": bool = false,
877877 sentinel: ?*Inst = null,
878878 size: std.builtin.TypeInfo.Pointer.Size = .One,
src-self-hosted/zir_sema.zig+46-1
......@@ -271,6 +271,14 @@ fn resolveType(mod: *Module, scope: *Scope, old_inst: *zir.Inst) !Type {
271271 return val.toType();
272272}
273273
274fn resolveInt(mod: *Module, scope: *Scope, old_inst: *zir.Inst, dest_type: Type) !u64 {
275 const new_inst = try resolveInst(mod, scope, old_inst);
276 const coerced = try mod.coerce(scope, dest_type, new_inst);
277 const val = try mod.resolveConstValue(scope, coerced);
278
279 return val.toUnsignedInt();
280}
281
274282pub fn resolveInstConst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!TypedValue {
275283 const new_inst = try resolveInst(mod, scope, old_inst);
276284 const val = try mod.resolveConstValue(scope, new_inst);
......@@ -1322,5 +1330,42 @@ fn analyzeInstSimplePtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp, m
13221330}
13231331
13241332fn analyzeInstPtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.PtrType) InnerError!*Inst {
1325 return mod.fail(scope, inst.base.src, "TODO implement ptr_type", .{});
1333 // TODO lazy values
1334 const @"align" = if (inst.kw_args.@"align") |some|
1335 @truncate(u32, try resolveInt(mod, scope, some, Type.initTag(.u32)))
1336 else
1337 0;
1338 const bit_offset = if (inst.kw_args.align_bit_start) |some|
1339 @truncate(u16, try resolveInt(mod, scope, some, Type.initTag(.u16)))
1340 else
1341 0;
1342 const host_size = if (inst.kw_args.align_bit_end) |some|
1343 @truncate(u16, try resolveInt(mod, scope, some, Type.initTag(.u16)))
1344 else
1345 0;
1346
1347 if (host_size != 0 and bit_offset >= host_size * 8)
1348 return mod.fail(scope, inst.base.src, "bit offset starts after end of host integer", .{});
1349
1350 const sentinel = if (inst.kw_args.sentinel) |some|
1351 (try resolveInstConst(mod, scope, some)).val
1352 else
1353 null;
1354
1355 const elem_type = try resolveType(mod, scope, inst.positionals.child_type);
1356
1357 const ty = try mod.ptrType(
1358 scope,
1359 inst.base.src,
1360 elem_type,
1361 sentinel,
1362 @"align",
1363 bit_offset,
1364 host_size,
1365 inst.kw_args.mutable,
1366 inst.kw_args.@"allowzero",
1367 inst.kw_args.@"volatile",
1368 inst.kw_args.size,
1369 );
1370 return mod.constType(scope, inst.base.src, ty);
13261371}