mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 21:08:36 +00:00
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`.
This commit is contained in:
parent
d4468affb7
commit
f58cbef165
@ -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: {
|
||||
|
||||
73
src/Sema.zig
73
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,
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const expect = std.testing.expect;
|
||||
|
||||
// normal comment
|
||||
@ -83,3 +84,11 @@ test "unicode escape in character literal" {
|
||||
test "unicode character in character literal" {
|
||||
try expect('💩' == 128169);
|
||||
}
|
||||
|
||||
fn first4KeysOfHomeRow() []const u8 {
|
||||
return "aoeu";
|
||||
}
|
||||
|
||||
test "return string from function" {
|
||||
try expect(mem.eql(u8, first4KeysOfHomeRow(), "aoeu"));
|
||||
}
|
||||
|
||||
@ -5,14 +5,6 @@ const expectEqualStrings = std.testing.expectEqualStrings;
|
||||
const mem = std.mem;
|
||||
const builtin = @import("builtin");
|
||||
|
||||
fn first4KeysOfHomeRow() []const u8 {
|
||||
return "aoeu";
|
||||
}
|
||||
|
||||
test "return string from function" {
|
||||
try expect(mem.eql(u8, first4KeysOfHomeRow(), "aoeu"));
|
||||
}
|
||||
|
||||
test "memcpy and memset intrinsics" {
|
||||
var foo: [20]u8 = undefined;
|
||||
var bar: [20]u8 = undefined;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user