mirror of
https://github.com/ziglang/zig.git
synced 2025-12-16 19:23:08 +00:00
InternPool: implement isSinglePointer
This commit is contained in:
parent
e77dede87e
commit
aa1bb5517d
31
src/Sema.zig
31
src/Sema.zig
@ -2086,7 +2086,7 @@ fn failWithUseOfAsync(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError
|
|||||||
|
|
||||||
fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, object_ty: Type, field_name: []const u8) CompileError {
|
fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, object_ty: Type, field_name: []const u8) CompileError {
|
||||||
const mod = sema.mod;
|
const mod = sema.mod;
|
||||||
const inner_ty = if (object_ty.isSinglePointer()) object_ty.childType() else object_ty;
|
const inner_ty = if (object_ty.isSinglePointer(mod)) object_ty.childType() else object_ty;
|
||||||
|
|
||||||
if (inner_ty.zigTypeTag(mod) == .Optional) opt: {
|
if (inner_ty.zigTypeTag(mod) == .Optional) opt: {
|
||||||
var buf: Type.Payload.ElemType = undefined;
|
var buf: Type.Payload.ElemType = undefined;
|
||||||
@ -3412,8 +3412,9 @@ fn indexablePtrLen(
|
|||||||
src: LazySrcLoc,
|
src: LazySrcLoc,
|
||||||
object: Air.Inst.Ref,
|
object: Air.Inst.Ref,
|
||||||
) CompileError!Air.Inst.Ref {
|
) CompileError!Air.Inst.Ref {
|
||||||
|
const mod = sema.mod;
|
||||||
const object_ty = sema.typeOf(object);
|
const object_ty = sema.typeOf(object);
|
||||||
const is_pointer_to = object_ty.isSinglePointer();
|
const is_pointer_to = object_ty.isSinglePointer(mod);
|
||||||
const indexable_ty = if (is_pointer_to) object_ty.childType() else object_ty;
|
const indexable_ty = if (is_pointer_to) object_ty.childType() else object_ty;
|
||||||
try checkIndexable(sema, block, src, indexable_ty);
|
try checkIndexable(sema, block, src, indexable_ty);
|
||||||
return sema.fieldVal(block, src, object, "len", src);
|
return sema.fieldVal(block, src, object, "len", src);
|
||||||
@ -12764,12 +12765,12 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||||||
.Pointer => try sema.resolveDefinedValue(block, rhs_src, rhs),
|
.Pointer => try sema.resolveDefinedValue(block, rhs_src, rhs),
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
}) |rhs_val| {
|
}) |rhs_val| {
|
||||||
const lhs_sub_val = if (lhs_ty.isSinglePointer())
|
const lhs_sub_val = if (lhs_ty.isSinglePointer(mod))
|
||||||
(try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).?
|
(try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).?
|
||||||
else
|
else
|
||||||
lhs_val;
|
lhs_val;
|
||||||
|
|
||||||
const rhs_sub_val = if (rhs_ty.isSinglePointer())
|
const rhs_sub_val = if (rhs_ty.isSinglePointer(mod))
|
||||||
(try sema.pointerDeref(block, rhs_src, rhs_val, rhs_ty)).?
|
(try sema.pointerDeref(block, rhs_src, rhs_val, rhs_ty)).?
|
||||||
else
|
else
|
||||||
rhs_val;
|
rhs_val;
|
||||||
@ -13022,7 +13023,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||||||
if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| {
|
if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| {
|
||||||
const final_len_including_sent = result_len + @boolToInt(lhs_info.sentinel != null);
|
const final_len_including_sent = result_len + @boolToInt(lhs_info.sentinel != null);
|
||||||
|
|
||||||
const lhs_sub_val = if (lhs_ty.isSinglePointer())
|
const lhs_sub_val = if (lhs_ty.isSinglePointer(mod))
|
||||||
(try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).?
|
(try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).?
|
||||||
else
|
else
|
||||||
lhs_val;
|
lhs_val;
|
||||||
@ -17588,7 +17589,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
|||||||
const elem_ty = blk: {
|
const elem_ty = blk: {
|
||||||
const air_inst = try sema.resolveInst(extra.data.elem_type);
|
const air_inst = try sema.resolveInst(extra.data.elem_type);
|
||||||
const ty = sema.analyzeAsType(block, elem_ty_src, air_inst) catch |err| {
|
const ty = sema.analyzeAsType(block, elem_ty_src, air_inst) catch |err| {
|
||||||
if (err == error.AnalysisFail and sema.err != null and sema.typeOf(air_inst).isSinglePointer()) {
|
if (err == error.AnalysisFail and sema.err != null and sema.typeOf(air_inst).isSinglePointer(mod)) {
|
||||||
try sema.errNote(block, elem_ty_src, sema.err.?, "use '.*' to dereference pointer", .{});
|
try sema.errNote(block, elem_ty_src, sema.err.?, "use '.*' to dereference pointer", .{});
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
@ -23902,7 +23903,7 @@ fn fieldVal(
|
|||||||
// Zig allows dereferencing a single pointer during field lookup. Note that
|
// Zig allows dereferencing a single pointer during field lookup. Note that
|
||||||
// we don't actually need to generate the dereference some field lookups, like the
|
// we don't actually need to generate the dereference some field lookups, like the
|
||||||
// length of arrays and other comptime operations.
|
// length of arrays and other comptime operations.
|
||||||
const is_pointer_to = object_ty.isSinglePointer();
|
const is_pointer_to = object_ty.isSinglePointer(mod);
|
||||||
|
|
||||||
const inner_ty = if (is_pointer_to)
|
const inner_ty = if (is_pointer_to)
|
||||||
object_ty.childType()
|
object_ty.childType()
|
||||||
@ -24092,7 +24093,7 @@ fn fieldPtr(
|
|||||||
// Zig allows dereferencing a single pointer during field lookup. Note that
|
// Zig allows dereferencing a single pointer during field lookup. Note that
|
||||||
// we don't actually need to generate the dereference some field lookups, like the
|
// we don't actually need to generate the dereference some field lookups, like the
|
||||||
// length of arrays and other comptime operations.
|
// length of arrays and other comptime operations.
|
||||||
const is_pointer_to = object_ty.isSinglePointer();
|
const is_pointer_to = object_ty.isSinglePointer(mod);
|
||||||
|
|
||||||
const inner_ty = if (is_pointer_to)
|
const inner_ty = if (is_pointer_to)
|
||||||
object_ty.childType()
|
object_ty.childType()
|
||||||
@ -25622,7 +25623,7 @@ fn coerceExtra(
|
|||||||
// *T to *[1]T
|
// *T to *[1]T
|
||||||
single_item: {
|
single_item: {
|
||||||
if (dest_info.size != .One) break :single_item;
|
if (dest_info.size != .One) break :single_item;
|
||||||
if (!inst_ty.isSinglePointer()) break :single_item;
|
if (!inst_ty.isSinglePointer(mod)) break :single_item;
|
||||||
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
|
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
|
||||||
const ptr_elem_ty = inst_ty.childType();
|
const ptr_elem_ty = inst_ty.childType();
|
||||||
const array_ty = dest_info.pointee_type;
|
const array_ty = dest_info.pointee_type;
|
||||||
@ -25639,7 +25640,7 @@ fn coerceExtra(
|
|||||||
|
|
||||||
// Coercions where the source is a single pointer to an array.
|
// Coercions where the source is a single pointer to an array.
|
||||||
src_array_ptr: {
|
src_array_ptr: {
|
||||||
if (!inst_ty.isSinglePointer()) break :src_array_ptr;
|
if (!inst_ty.isSinglePointer(mod)) break :src_array_ptr;
|
||||||
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
|
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
|
||||||
const array_ty = inst_ty.childType();
|
const array_ty = inst_ty.childType();
|
||||||
if (array_ty.zigTypeTag(mod) != .Array) break :src_array_ptr;
|
if (array_ty.zigTypeTag(mod) != .Array) break :src_array_ptr;
|
||||||
@ -25794,7 +25795,7 @@ fn coerceExtra(
|
|||||||
.One => switch (dest_info.pointee_type.zigTypeTag(mod)) {
|
.One => switch (dest_info.pointee_type.zigTypeTag(mod)) {
|
||||||
.Union => {
|
.Union => {
|
||||||
// pointer to anonymous struct to pointer to union
|
// pointer to anonymous struct to pointer to union
|
||||||
if (inst_ty.isSinglePointer() and
|
if (inst_ty.isSinglePointer(mod) and
|
||||||
inst_ty.childType().isAnonStruct() and
|
inst_ty.childType().isAnonStruct() and
|
||||||
sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
|
sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
|
||||||
{
|
{
|
||||||
@ -25803,7 +25804,7 @@ fn coerceExtra(
|
|||||||
},
|
},
|
||||||
.Struct => {
|
.Struct => {
|
||||||
// pointer to anonymous struct to pointer to struct
|
// pointer to anonymous struct to pointer to struct
|
||||||
if (inst_ty.isSinglePointer() and
|
if (inst_ty.isSinglePointer(mod) and
|
||||||
inst_ty.childType().isAnonStruct() and
|
inst_ty.childType().isAnonStruct() and
|
||||||
sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
|
sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
|
||||||
{
|
{
|
||||||
@ -25815,7 +25816,7 @@ fn coerceExtra(
|
|||||||
},
|
},
|
||||||
.Array => {
|
.Array => {
|
||||||
// pointer to tuple to pointer to array
|
// pointer to tuple to pointer to array
|
||||||
if (inst_ty.isSinglePointer() and
|
if (inst_ty.isSinglePointer(mod) and
|
||||||
inst_ty.childType().isTuple() and
|
inst_ty.childType().isTuple() and
|
||||||
sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
|
sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
|
||||||
{
|
{
|
||||||
@ -25834,7 +25835,7 @@ fn coerceExtra(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inst_ty.isSinglePointer()) break :to_slice;
|
if (!inst_ty.isSinglePointer(mod)) break :to_slice;
|
||||||
const inst_child_ty = inst_ty.childType();
|
const inst_child_ty = inst_ty.childType();
|
||||||
if (!inst_child_ty.isTuple()) break :to_slice;
|
if (!inst_child_ty.isTuple()) break :to_slice;
|
||||||
|
|
||||||
@ -30807,7 +30808,7 @@ fn resolvePeerTypes(
|
|||||||
.Vector => continue,
|
.Vector => continue,
|
||||||
else => {},
|
else => {},
|
||||||
},
|
},
|
||||||
.Fn => if (chosen_ty.isSinglePointer() and chosen_ty.isConstPtr() and chosen_ty.childType().zigTypeTag(mod) == .Fn) {
|
.Fn => if (chosen_ty.isSinglePointer(mod) and chosen_ty.isConstPtr() and chosen_ty.childType().zigTypeTag(mod) == .Fn) {
|
||||||
if (.ok == try sema.coerceInMemoryAllowedFns(block, chosen_ty.childType(), candidate_ty, target, src, src)) {
|
if (.ok == try sema.coerceInMemoryAllowedFns(block, chosen_ty.childType(), candidate_ty, target, src, src)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3873,7 +3873,7 @@ fn airCmpOp(
|
|||||||
try reap(f, inst, &.{ data.lhs, data.rhs });
|
try reap(f, inst, &.{ data.lhs, data.rhs });
|
||||||
|
|
||||||
const rhs_ty = f.typeOf(data.rhs);
|
const rhs_ty = f.typeOf(data.rhs);
|
||||||
const need_cast = lhs_ty.isSinglePointer() or rhs_ty.isSinglePointer();
|
const need_cast = lhs_ty.isSinglePointer(mod) or rhs_ty.isSinglePointer(mod);
|
||||||
const writer = f.object.writer();
|
const writer = f.object.writer();
|
||||||
const local = try f.allocLocal(inst, inst_ty);
|
const local = try f.allocLocal(inst, inst_ty);
|
||||||
const v = try Vectorize.start(f, inst, writer, lhs_ty);
|
const v = try Vectorize.start(f, inst, writer, lhs_ty);
|
||||||
|
|||||||
@ -5929,7 +5929,7 @@ pub const FuncGen = struct {
|
|||||||
const base_ptr = try self.resolveInst(bin_op.lhs);
|
const base_ptr = try self.resolveInst(bin_op.lhs);
|
||||||
const rhs = try self.resolveInst(bin_op.rhs);
|
const rhs = try self.resolveInst(bin_op.rhs);
|
||||||
// TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch
|
// TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch
|
||||||
const ptr = if (ptr_ty.isSinglePointer()) ptr: {
|
const ptr = if (ptr_ty.isSinglePointer(mod)) ptr: {
|
||||||
// If this is a single-item pointer to an array, we need another index in the GEP.
|
// If this is a single-item pointer to an array, we need another index in the GEP.
|
||||||
const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };
|
const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };
|
||||||
break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
|
break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
|
||||||
@ -5962,7 +5962,7 @@ pub const FuncGen = struct {
|
|||||||
if (elem_ptr.ptrInfo().data.vector_index != .none) return base_ptr;
|
if (elem_ptr.ptrInfo().data.vector_index != .none) return base_ptr;
|
||||||
|
|
||||||
const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty);
|
const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty);
|
||||||
if (ptr_ty.isSinglePointer()) {
|
if (ptr_ty.isSinglePointer(mod)) {
|
||||||
// If this is a single-item pointer to an array, we need another index in the GEP.
|
// If this is a single-item pointer to an array, we need another index in the GEP.
|
||||||
const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };
|
const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };
|
||||||
return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
|
return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
|
||||||
|
|||||||
19
src/type.zig
19
src/type.zig
@ -4039,8 +4039,9 @@ pub const Type = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn isSinglePointer(self: Type) bool {
|
pub fn isSinglePointer(ty: Type, mod: *const Module) bool {
|
||||||
return switch (self.tag()) {
|
switch (ty.ip_index) {
|
||||||
|
.none => return switch (ty.tag()) {
|
||||||
.single_const_pointer,
|
.single_const_pointer,
|
||||||
.single_mut_pointer,
|
.single_mut_pointer,
|
||||||
.single_const_pointer_to_comptime_int,
|
.single_const_pointer_to_comptime_int,
|
||||||
@ -4048,10 +4049,15 @@ pub const Type = struct {
|
|||||||
.inferred_alloc_mut,
|
.inferred_alloc_mut,
|
||||||
=> true,
|
=> true,
|
||||||
|
|
||||||
.pointer => self.castTag(.pointer).?.data.size == .One,
|
.pointer => ty.castTag(.pointer).?.data.size == .One,
|
||||||
|
|
||||||
else => false,
|
else => false,
|
||||||
};
|
},
|
||||||
|
else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||||
|
.ptr_type => |ptr_info| ptr_info.size == .One,
|
||||||
|
else => false,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Asserts `ty` is a pointer.
|
/// Asserts `ty` is a pointer.
|
||||||
@ -6142,6 +6148,11 @@ pub const Type = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn declSrcLocOrNull(ty: Type, mod: *Module) ?Module.SrcLoc {
|
pub fn declSrcLocOrNull(ty: Type, mod: *Module) ?Module.SrcLoc {
|
||||||
|
if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||||
|
.struct_type => @panic("TODO"),
|
||||||
|
.union_type => @panic("TODO"),
|
||||||
|
else => return null,
|
||||||
|
};
|
||||||
switch (ty.tag()) {
|
switch (ty.tag()) {
|
||||||
.enum_full, .enum_nonexhaustive => {
|
.enum_full, .enum_nonexhaustive => {
|
||||||
const enum_full = ty.cast(Payload.EnumFull).?.data;
|
const enum_full = ty.cast(Payload.EnumFull).?.data;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user