From c507e0b76396a200392e16b92292bfc442c6421f Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Mon, 18 Oct 2021 15:09:13 +0200 Subject: [PATCH] stage2: Sema.fieldPtr for slice ptr and len --- src/Sema.zig | 63 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index a07c5761ff..7b4eafe1d4 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -10897,27 +10897,52 @@ fn fieldPtr( } }, .Pointer => if (inner_ty.isSlice()) { - // Here for the ptr and len fields what we need to do is the situation - // when a temporary has its address taken, e.g. `&a[c..d].len`. - // This value may be known at compile-time or runtime. In the former - // case, it should create an anonymous Decl and return a decl_ref to it. - // In the latter case, it should add an `alloc` instruction, store - // the runtime value to it, and then return the `alloc`. - // In both cases the pointer should be const. + const inner_ptr = if (is_pointer_to) + try sema.analyzeLoad(block, src, object_ptr, object_ptr_src) + else + object_ptr; + if (mem.eql(u8, field_name, "ptr")) { - return sema.fail( - block, - field_name_src, - "TODO: implement reference to 'ptr' field of slice '{}'", - .{inner_ty}, - ); + const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer); + const slice_ptr_ty = inner_ty.slicePtrFieldType(buf); + + if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| { + var anon_decl = try block.startAnonDecl(); + defer anon_decl.deinit(); + + return sema.analyzeDeclRef(try anon_decl.finish( + try slice_ptr_ty.copy(anon_decl.arena()), + try val.slicePtr().copy(anon_decl.arena()), + )); + } + try sema.requireRuntimeBlock(block, src); + + const result_ty = try Type.ptr(sema.arena, .{ + .pointee_type = slice_ptr_ty, + .mutable = object_ptr_ty.ptrIsMutable(), + .@"addrspace" = object_ptr_ty.ptrAddressSpace(), + }); + + return block.addTyOp(.ptr_slice_ptr_ptr, result_ty, inner_ptr); } else if (mem.eql(u8, field_name, "len")) { - return sema.fail( - block, - field_name_src, - "TODO: implement reference to 'len' field of slice '{}'", - .{inner_ty}, - ); + if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| { + var anon_decl = try block.startAnonDecl(); + defer anon_decl.deinit(); + + return sema.analyzeDeclRef(try anon_decl.finish( + Type.usize, + try Value.Tag.int_u64.create(anon_decl.arena(), val.sliceLen()), + )); + } + try sema.requireRuntimeBlock(block, src); + + const result_ty = try Type.ptr(sema.arena, .{ + .pointee_type = Type.usize, + .mutable = object_ptr_ty.ptrIsMutable(), + .@"addrspace" = object_ptr_ty.ptrAddressSpace(), + }); + + return block.addTyOp(.ptr_slice_len_ptr, result_ty, inner_ptr); } else { return sema.fail( block,