diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-08-04 23:02:13 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-08-04 23:02:13 -0700 |
| commit | f58cbef1659742e57377d3f8c92a0b9b97af91ad (patch) | |
| tree | 43bc60f54b5a4252df309d9c3cb5dbe3aca20297 /src | |
| parent | d4468affb751668e156230c32b29c84684825b4f (diff) | |
| download | zig-f58cbef1659742e57377d3f8c92a0b9b97af91ad.tar.gz zig-f58cbef1659742e57377d3f8c92a0b9b97af91ad.zip | |
stage2: std.mem.eql works now
* The `indexable_ptr_len` ZIR instruction now uses a `none_or_ref`
ResultLoc. This prevents an unnecessary `ref` instruction from being
emitted.
* Sema: Fix `analyzeCall` using the incorrect ZIR object for the
generic function callee.
* LLVM backend: `genTypedValue` supports a `Slice` type encoded with
the `decl_ref` `Value`.
Diffstat (limited to 'src')
| -rw-r--r-- | src/AstGen.zig | 2 | ||||
| -rw-r--r-- | src/Sema.zig | 73 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 30 |
3 files changed, 66 insertions, 39 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig index 493e0a75f4..9886e4d809 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -5423,7 +5423,7 @@ fn forExpr( const tree = astgen.tree; const token_tags = tree.tokens.items(.tag); - const array_ptr = try expr(parent_gz, scope, .ref, for_full.ast.cond_expr); + const array_ptr = try expr(parent_gz, scope, .none_or_ref, for_full.ast.cond_expr); const len = try parent_gz.addUnNode(.indexable_ptr_len, array_ptr, for_full.ast.cond_expr); const index_ptr = blk: { diff --git a/src/Sema.zig b/src/Sema.zig index 8bcdcb63c9..dff11301db 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -1306,38 +1306,44 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); - const array_ptr = sema.resolveInst(inst_data.operand); - const array_ptr_src = src; + const array = sema.resolveInst(inst_data.operand); + const array_ty = sema.typeOf(array); - const elem_ty = sema.typeOf(array_ptr).elemType(); - if (elem_ty.isSlice()) { - const slice_inst = try sema.analyzeLoad(block, src, array_ptr, array_ptr_src); - return sema.analyzeSliceLen(block, src, slice_inst); + if (array_ty.isSlice()) { + return sema.analyzeSliceLen(block, src, array); } - if (!elem_ty.isIndexable()) { - const cond_src: LazySrcLoc = .{ .node_offset_for_cond = inst_data.src_node }; - const msg = msg: { - const msg = try sema.mod.errMsg( - &block.base, - cond_src, - "type '{}' does not support indexing", - .{elem_ty}, - ); - errdefer msg.destroy(sema.gpa); - try sema.mod.errNote( - &block.base, - cond_src, - msg, - "for loop operand must be an array, slice, tuple, or vector", - .{}, - ); - break :msg msg; - }; - return sema.mod.failWithOwnedErrorMsg(&block.base, msg); + + if (array_ty.isSinglePointer()) { + const elem_ty = array_ty.elemType(); + if (elem_ty.isSlice()) { + const slice_inst = try sema.analyzeLoad(block, src, array, src); + return sema.analyzeSliceLen(block, src, slice_inst); + } + if (!elem_ty.isIndexable()) { + const msg = msg: { + const msg = try sema.mod.errMsg( + &block.base, + src, + "type '{}' does not support indexing", + .{elem_ty}, + ); + errdefer msg.destroy(sema.gpa); + try sema.mod.errNote( + &block.base, + src, + msg, + "for loop operand must be an array, slice, tuple, or vector", + .{}, + ); + break :msg msg; + }; + return sema.mod.failWithOwnedErrorMsg(&block.base, msg); + } + const result_ptr = try sema.fieldPtr(block, src, array, "len", src); + return sema.analyzeLoad(block, src, result_ptr, src); } - const result_ptr = try sema.fieldPtr(block, src, array_ptr, "len", src); - const result_ptr_src = array_ptr_src; - return sema.analyzeLoad(block, src, result_ptr, result_ptr_src); + + return sema.mod.fail(&block.base, src, "TODO implement Sema.zirIndexablePtrLen", .{}); } fn zirAllocExtended( @@ -2520,10 +2526,11 @@ fn analyzeCall( // generic Scope only to junk it if it matches an existing instantiation. // TODO - const fn_info = sema.code.getFnInfo(module_fn.zir_body_inst); - const zir_tags = sema.code.instructions.items(.tag); + const namespace = module_fn.owner_decl.namespace; + const fn_zir = namespace.file_scope.zir; + const fn_info = fn_zir.getFnInfo(module_fn.zir_body_inst); + const zir_tags = fn_zir.instructions.items(.tag); const new_func = new_func: { - const namespace = module_fn.owner_decl.namespace; try namespace.anon_decls.ensureUnusedCapacity(gpa, 1); // Create a Decl for the new function. @@ -2558,7 +2565,7 @@ fn analyzeCall( .mod = mod, .gpa = gpa, .arena = sema.arena, - .code = sema.code, + .code = fn_zir, .owner_decl = new_decl, .namespace = namespace, .func = null, diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 4a589ea66d..0e73469687 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -701,11 +701,31 @@ pub const DeclGen = struct { }, .Pointer => switch (tv.val.tag()) { .decl_ref => { - const decl = tv.val.castTag(.decl_ref).?.data; - decl.alive = true; - const val = try self.resolveGlobalDecl(decl); - const llvm_type = try self.llvmType(tv.ty); - return val.constBitCast(llvm_type); + if (tv.ty.isSlice()) { + var buf: Type.Payload.ElemType = undefined; + const ptr_ty = tv.ty.slicePtrFieldType(&buf); + var slice_len: Value.Payload.U64 = .{ + .base = .{ .tag = .int_u64 }, + .data = tv.val.sliceLen(), + }; + const fields: [2]*const llvm.Value = .{ + try self.genTypedValue(.{ + .ty = ptr_ty, + .val = tv.val, + }), + try self.genTypedValue(.{ + .ty = Type.initTag(.usize), + .val = Value.initPayload(&slice_len.base), + }), + }; + return self.context.constStruct(&fields, fields.len, .False); + } else { + const decl = tv.val.castTag(.decl_ref).?.data; + decl.alive = true; + const val = try self.resolveGlobalDecl(decl); + const llvm_type = try self.llvmType(tv.ty); + return val.constBitCast(llvm_type); + } }, .variable => { const decl = tv.val.castTag(.variable).?.data.owner_decl; |
