authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-18 15:09:13+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-20 03:44:02+02:00
logc507e0b76396a200392e16b92292bfc442c6421f
tree6d6c62c3bc13e503be8805ef59bf932cfc76a081
parent05c5c99a95c894d7e3241e1729e09aa7eacb6035

stage2: Sema.fieldPtr for slice ptr and len


1 files changed, 44 insertions(+), 19 deletions(-)

src/Sema.zig+44-19
...@@ -10897,27 +10897,52 @@ fn fieldPtr(...@@ -10897,27 +10897,52 @@ fn fieldPtr(
10897 }10897 }
10898 },10898 },
10899 .Pointer => if (inner_ty.isSlice()) {10899 .Pointer => if (inner_ty.isSlice()) {
10900 // Here for the ptr and len fields what we need to do is the situation10900 const inner_ptr = if (is_pointer_to)
10901 // when a temporary has its address taken, e.g. `&a[c..d].len`.10901 try sema.analyzeLoad(block, src, object_ptr, object_ptr_src)
10902 // This value may be known at compile-time or runtime. In the former10902 else
10903 // case, it should create an anonymous Decl and return a decl_ref to it.10903 object_ptr;
10904 // In the latter case, it should add an `alloc` instruction, store10904
10905 // the runtime value to it, and then return the `alloc`.
10906 // In both cases the pointer should be const.
10907 if (mem.eql(u8, field_name, "ptr")) {10905 if (mem.eql(u8, field_name, "ptr")) {
10908 return sema.fail(10906 const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer);
10909 block,10907 const slice_ptr_ty = inner_ty.slicePtrFieldType(buf);
10910 field_name_src,10908
10911 "TODO: implement reference to 'ptr' field of slice '{}'",10909 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
10912 .{inner_ty},10910 var anon_decl = try block.startAnonDecl();
10913 );10911 defer anon_decl.deinit();
10912
10913 return sema.analyzeDeclRef(try anon_decl.finish(
10914 try slice_ptr_ty.copy(anon_decl.arena()),
10915 try val.slicePtr().copy(anon_decl.arena()),
10916 ));
10917 }
10918 try sema.requireRuntimeBlock(block, src);
10919
10920 const result_ty = try Type.ptr(sema.arena, .{
10921 .pointee_type = slice_ptr_ty,
10922 .mutable = object_ptr_ty.ptrIsMutable(),
10923 .@"addrspace" = object_ptr_ty.ptrAddressSpace(),
10924 });
10925
10926 return block.addTyOp(.ptr_slice_ptr_ptr, result_ty, inner_ptr);
10914 } else if (mem.eql(u8, field_name, "len")) {10927 } else if (mem.eql(u8, field_name, "len")) {
10915 return sema.fail(10928 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
10916 block,10929 var anon_decl = try block.startAnonDecl();
10917 field_name_src,10930 defer anon_decl.deinit();
10918 "TODO: implement reference to 'len' field of slice '{}'",10931
10919 .{inner_ty},10932 return sema.analyzeDeclRef(try anon_decl.finish(
10920 );10933 Type.usize,
10934 try Value.Tag.int_u64.create(anon_decl.arena(), val.sliceLen()),
10935 ));
10936 }
10937 try sema.requireRuntimeBlock(block, src);
10938
10939 const result_ty = try Type.ptr(sema.arena, .{
10940 .pointee_type = Type.usize,
10941 .mutable = object_ptr_ty.ptrIsMutable(),
10942 .@"addrspace" = object_ptr_ty.ptrAddressSpace(),
10943 });
10944
10945 return block.addTyOp(.ptr_slice_len_ptr, result_ty, inner_ptr);
10921 } else {10946 } else {
10922 return sema.fail(10947 return sema.fail(
10923 block,10948 block,