aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/InternPool.zig38
-rw-r--r--src/Module.zig2
-rw-r--r--src/Sema.zig11
-rw-r--r--src/arch/aarch64/CodeGen.zig2
-rw-r--r--src/arch/arm/CodeGen.zig2
-rw-r--r--src/arch/sparc64/CodeGen.zig2
-rw-r--r--src/arch/x86_64/CodeGen.zig11
-rw-r--r--src/codegen.zig6
-rw-r--r--src/codegen/c.zig13
-rw-r--r--src/codegen/c/type.zig2
-rw-r--r--src/codegen/llvm.zig14
-rw-r--r--src/codegen/spirv.zig6
-rw-r--r--src/link/Dwarf.zig2
-rw-r--r--src/type.zig66
-rw-r--r--src/value.zig8
15 files changed, 120 insertions, 65 deletions
diff --git a/src/InternPool.zig b/src/InternPool.zig
index de69b19dbe..15b6e318ed 100644
--- a/src/InternPool.zig
+++ b/src/InternPool.zig
@@ -668,6 +668,9 @@ pub const Tag = enum(u8) {
/// A fully explicitly specified pointer type.
/// data is payload to Pointer.
type_pointer,
+ /// A slice type.
+ /// data is Index of underlying pointer type.
+ type_slice,
/// An optional type.
/// data is the child type.
type_optional,
@@ -984,6 +987,13 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
} };
},
+ .type_slice => {
+ const ptr_ty_index = @intToEnum(Index, data);
+ var result = indexToKey(ip, ptr_ty_index);
+ result.ptr_type.size = .Slice;
+ return result;
+ },
+
.type_optional => .{ .opt_type = @intToEnum(Index, data) },
.type_error_union => @panic("TODO"),
@@ -1041,6 +1051,19 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
},
.ptr_type => |ptr_type| {
assert(ptr_type.elem_type != .none);
+
+ if (ptr_type.size == .Slice) {
+ var new_key = key;
+ new_key.ptr_type.size = .Many;
+ const ptr_ty_index = try get(ip, gpa, new_key);
+ try ip.items.ensureUnusedCapacity(gpa, 1);
+ ip.items.appendAssumeCapacity(.{
+ .tag = .type_slice,
+ .data = @enumToInt(ptr_ty_index),
+ });
+ return @intToEnum(Index, ip.items.len - 1);
+ }
+
// TODO introduce more pointer encodings
ip.items.appendAssumeCapacity(.{
.tag = .type_pointer,
@@ -1401,6 +1424,20 @@ pub fn childType(ip: InternPool, i: Index) Index {
};
}
+/// Given a slice type, returns the type of the pointer field.
+pub fn slicePtrType(ip: InternPool, i: Index) Index {
+ switch (i) {
+ .const_slice_u8_type => return .manyptr_const_u8_type,
+ .const_slice_u8_sentinel_0_type => return .manyptr_const_u8_sentinel_0_type,
+ else => {},
+ }
+ const item = ip.items.get(@enumToInt(i));
+ switch (item.tag) {
+ .type_slice => return @intToEnum(Index, item.data),
+ else => unreachable, // not a slice type
+ }
+}
+
pub fn dump(ip: InternPool) void {
dumpFallible(ip, std.heap.page_allocator) catch return;
}
@@ -1438,6 +1475,7 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void {
.type_array => @sizeOf(Vector),
.type_vector => @sizeOf(Vector),
.type_pointer => @sizeOf(Pointer),
+ .type_slice => 0,
.type_optional => 0,
.type_error_union => @sizeOf(ErrorUnion),
.type_enum_simple => @sizeOf(EnumSimple),
diff --git a/src/Module.zig b/src/Module.zig
index e9658ad89f..01e2403377 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -6553,7 +6553,7 @@ pub fn populateTestFunctions(
}
const decl = mod.declPtr(decl_index);
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const tmp_test_fn_ty = decl.ty.slicePtrFieldType(&buf).childType(mod);
+ const tmp_test_fn_ty = decl.ty.slicePtrFieldType(&buf, mod).childType(mod);
const array_decl_index = d: {
// Add mod.test_functions to an array decl then make the test_functions
diff --git a/src/Sema.zig b/src/Sema.zig
index 088d830280..ced5eb247c 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -24201,7 +24201,7 @@ fn fieldPtr(
if (mem.eql(u8, field_name, "ptr")) {
const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer);
- const slice_ptr_ty = inner_ty.slicePtrFieldType(buf);
+ const slice_ptr_ty = inner_ty.slicePtrFieldType(buf, mod);
const result_ty = try Type.ptr(sema.arena, sema.mod, .{
.pointee_type = slice_ptr_ty,
@@ -27804,7 +27804,7 @@ fn beginComptimePtrMutation(
sema,
block,
src,
- parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer)),
+ parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer), mod),
&val_ptr.castTag(.slice).?.data.ptr,
ptr_elem_ty,
parent.decl_ref_mut,
@@ -27859,7 +27859,7 @@ fn beginComptimePtrMutation(
sema,
block,
src,
- parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer)),
+ parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer), mod),
&val_ptr.castTag(.slice).?.data.ptr,
ptr_elem_ty,
parent.decl_ref_mut,
@@ -28256,7 +28256,7 @@ fn beginComptimePtrLoad(
const slice_val = tv.val.castTag(.slice).?.data;
deref.pointee = switch (field_index) {
Value.Payload.Slice.ptr_index => TypedValue{
- .ty = field_ptr.container_ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer)),
+ .ty = field_ptr.container_ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer), mod),
.val = slice_val.ptr,
},
Value.Payload.Slice.len_index => TypedValue{
@@ -29339,8 +29339,9 @@ fn analyzeSlicePtr(
slice: Air.Inst.Ref,
slice_ty: Type,
) CompileError!Air.Inst.Ref {
+ const mod = sema.mod;
const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer);
- const result_ty = slice_ty.slicePtrFieldType(buf);
+ const result_ty = slice_ty.slicePtrFieldType(buf, mod);
if (try sema.resolveMaybeUndefVal(slice)) |val| {
if (val.isUndef()) return sema.addConstUndef(result_ty);
return sema.addConstant(result_ty, val.slicePtr());
diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig
index 4a10691e02..95a8350c7d 100644
--- a/src/arch/aarch64/CodeGen.zig
+++ b/src/arch/aarch64/CodeGen.zig
@@ -3435,7 +3435,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
const slice_ty = self.typeOf(bin_op.lhs);
const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const ptr_ty = slice_ty.slicePtrFieldType(&buf);
+ const ptr_ty = slice_ty.slicePtrFieldType(&buf, mod);
const slice_mcv = try self.resolveInst(bin_op.lhs);
const base_mcv = slicePtr(slice_mcv);
diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig
index 3591ead53d..cc2bc3a613 100644
--- a/src/arch/arm/CodeGen.zig
+++ b/src/arch/arm/CodeGen.zig
@@ -2433,7 +2433,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
const slice_ty = self.typeOf(bin_op.lhs);
const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const ptr_ty = slice_ty.slicePtrFieldType(&buf);
+ const ptr_ty = slice_ty.slicePtrFieldType(&buf, mod);
const slice_mcv = try self.resolveInst(bin_op.lhs);
const base_mcv = slicePtr(slice_mcv);
diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig
index 83e4b4f93d..4231222d4b 100644
--- a/src/arch/sparc64/CodeGen.zig
+++ b/src/arch/sparc64/CodeGen.zig
@@ -2462,7 +2462,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
const elem_size = elem_ty.abiSize(mod);
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);
+ const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf, mod);
const index_lock: ?RegisterLock = if (index_mcv == .register)
self.register_manager.lockRegAssumeUnused(index_mcv.register)
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig
index f6304a0ff3..ee604afd0f 100644
--- a/src/arch/x86_64/CodeGen.zig
+++ b/src/arch/x86_64/CodeGen.zig
@@ -4056,7 +4056,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
const elem_ty = slice_ty.childType(mod);
const elem_size = elem_ty.abiSize(mod);
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);
+ const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf, mod);
const index_ty = self.typeOf(rhs);
const index_mcv = try self.resolveInst(rhs);
@@ -4081,11 +4081,12 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
}
fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
+ const mod = self.bin_file.options.module.?;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const slice_ty = self.typeOf(bin_op.lhs);
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);
+ const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf, mod);
const elem_ptr = try self.genSliceElemPtr(bin_op.lhs, bin_op.rhs);
const dst_mcv = try self.allocRegOrMem(inst, false);
try self.load(dst_mcv, slice_ptr_field_type, elem_ptr);
@@ -8682,7 +8683,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))
- .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(&ptr_buf) else pl_ty }
+ .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(&ptr_buf, mod) else pl_ty }
else
.{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool };
@@ -8774,7 +8775,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))
- .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(&ptr_buf) else pl_ty }
+ .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(&ptr_buf, mod) else pl_ty }
else
.{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool };
@@ -10813,7 +10814,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
switch (dst_ptr_ty.ptrSize(mod)) {
.Slice => {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const slice_ptr_ty = dst_ptr_ty.slicePtrFieldType(&buf);
+ const slice_ptr_ty = dst_ptr_ty.slicePtrFieldType(&buf, mod);
// TODO: this only handles slices stored in the stack
const ptr = dst_ptr;
diff --git a/src/codegen.zig b/src/codegen.zig
index 25e8d892d8..5f5a3f66be 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -361,7 +361,7 @@ pub fn generateSymbol(
// generate ptr
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf);
+ const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf, mod);
switch (try generateSymbol(bin_file, src_loc, .{
.ty = slice_ptr_field_type,
.val = slice.ptr,
@@ -851,7 +851,7 @@ fn lowerParentPtr(
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
break :offset switch (field_ptr.field_index) {
0 => 0,
- 1 => field_ptr.container_ty.slicePtrFieldType(&buf).abiSize(mod),
+ 1 => field_ptr.container_ty.slicePtrFieldType(&buf, mod).abiSize(mod),
else => unreachable,
};
},
@@ -951,7 +951,7 @@ fn lowerDeclRef(
if (typed_value.ty.isSlice(mod)) {
// generate ptr
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf);
+ const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf, mod);
switch (try generateSymbol(bin_file, src_loc, .{
.ty = slice_ptr_field_type,
.val = typed_value.val,
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index b0fb9fa480..039c75de67 100644
--- a/src/codegen/c.zig
+++ b/src/codegen/c.zig
@@ -566,7 +566,7 @@ pub const DeclGen = struct {
}
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
- try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr(), .Initializer);
+ try dg.renderValue(writer, ty.slicePtrFieldType(&buf, mod), val.slicePtr(), .Initializer);
var len_pl: Value.Payload.U64 = .{
.base = .{ .tag = .int_u64 },
@@ -787,7 +787,7 @@ pub const DeclGen = struct {
try writer.writeAll("{(");
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const ptr_ty = ty.slicePtrFieldType(&buf);
+ const ptr_ty = ty.slicePtrFieldType(&buf, mod);
try dg.renderType(writer, ptr_ty);
return writer.print("){x}, {0x}}}", .{try dg.fmtIntLiteral(Type.usize, val, .Other)});
} else {
@@ -1088,7 +1088,7 @@ pub const DeclGen = struct {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
try writer.writeByte('{');
- try dg.renderValue(writer, ty.slicePtrFieldType(&buf), slice.ptr, initializer_type);
+ try dg.renderValue(writer, ty.slicePtrFieldType(&buf, mod), slice.ptr, initializer_type);
try writer.writeAll(", ");
try dg.renderValue(writer, Type.usize, slice.len, initializer_type);
try writer.writeByte('}');
@@ -4107,6 +4107,7 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
}
fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
+ const mod = f.object.dg.module;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
@@ -4116,7 +4117,7 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
const inst_ty = f.typeOfIndex(inst);
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const ptr_ty = inst_ty.slicePtrFieldType(&buf);
+ const ptr_ty = inst_ty.slicePtrFieldType(&buf, mod);
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
@@ -5112,7 +5113,7 @@ fn airIsNull(
TypedValue{ .ty = payload_ty, .val = Value.zero }
else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: {
try writer.writeAll(".ptr");
- const slice_ptr_ty = payload_ty.slicePtrFieldType(&slice_ptr_buf);
+ const slice_ptr_ty = payload_ty.slicePtrFieldType(&slice_ptr_buf, mod);
break :rhs TypedValue{ .ty = slice_ptr_ty, .val = Value.null };
} else rhs: {
try writer.writeAll(".is_null");
@@ -5845,7 +5846,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
// &(*(void *)p)[0], although LLVM does via GetElementPtr
if (operand == .undef) {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
- try f.writeCValue(writer, .{ .undef = inst_ty.slicePtrFieldType(&buf) }, .Initializer);
+ try f.writeCValue(writer, .{ .undef = inst_ty.slicePtrFieldType(&buf, mod) }, .Initializer);
} else if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) {
try writer.writeAll("&(");
try f.writeCValueDeref(writer, operand);
diff --git a/src/codegen/c/type.zig b/src/codegen/c/type.zig
index 9e6de6cb21..84ddce6809 100644
--- a/src/codegen/c/type.zig
+++ b/src/codegen/c/type.zig
@@ -1432,7 +1432,7 @@ pub const CType = extern union {
.payload => unreachable,
}) |fwd_idx| {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const ptr_ty = ty.slicePtrFieldType(&buf);
+ const ptr_ty = ty.slicePtrFieldType(&buf, mod);
if (try lookup.typeToIndex(ptr_ty, kind)) |ptr_idx| {
self.storage = .{ .anon = undefined };
self.storage.anon.fields[0] = .{
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 7fa9b74334..5289becf1e 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -1638,7 +1638,7 @@ pub const Object = struct {
if (ty.isSlice(mod)) {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const ptr_ty = ty.slicePtrFieldType(&buf);
+ const ptr_ty = ty.slicePtrFieldType(&buf, mod);
const len_ty = Type.usize;
const name = try ty.nameAlloc(gpa, o.module);
@@ -2822,7 +2822,7 @@ pub const DeclGen = struct {
.Pointer => {
if (t.isSlice(mod)) {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const ptr_type = t.slicePtrFieldType(&buf);
+ const ptr_type = t.slicePtrFieldType(&buf, mod);
const fields: [2]*llvm.Type = .{
try dg.lowerType(ptr_type),
@@ -3182,9 +3182,9 @@ pub const DeclGen = struct {
const param_ty = fn_info.param_types[it.zig_index - 1];
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = if (param_ty.zigTypeTag(mod) == .Optional)
- param_ty.optionalChild(mod).slicePtrFieldType(&buf)
+ param_ty.optionalChild(mod).slicePtrFieldType(&buf, mod)
else
- param_ty.slicePtrFieldType(&buf);
+ param_ty.slicePtrFieldType(&buf, mod);
const ptr_llvm_ty = try dg.lowerType(ptr_ty);
const len_llvm_ty = try dg.lowerType(Type.usize);
@@ -3387,7 +3387,7 @@ pub const DeclGen = struct {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const fields: [2]*llvm.Value = .{
try dg.lowerValue(.{
- .ty = tv.ty.slicePtrFieldType(&buf),
+ .ty = tv.ty.slicePtrFieldType(&buf, mod),
.val = slice.ptr,
}),
try dg.lowerValue(.{
@@ -4169,7 +4169,7 @@ pub const DeclGen = struct {
const mod = self.module;
if (tv.ty.isSlice(mod)) {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const ptr_ty = tv.ty.slicePtrFieldType(&buf);
+ const ptr_ty = tv.ty.slicePtrFieldType(&buf, mod);
var slice_len: Value.Payload.U64 = .{
.base = .{ .tag = .int_u64 },
.data = tv.val.sliceLen(mod),
@@ -6654,7 +6654,7 @@ pub const FuncGen = struct {
if (payload_ty.isSlice(mod)) {
const slice_ptr = self.builder.buildExtractValue(loaded, 0, "");
var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const ptr_ty = try self.dg.lowerType(payload_ty.slicePtrFieldType(&slice_buf));
+ const ptr_ty = try self.dg.lowerType(payload_ty.slicePtrFieldType(&slice_buf, mod));
return self.builder.buildICmp(pred, slice_ptr, ptr_ty.constNull(), "");
}
return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), "");
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig
index 27a79c1c45..e3b5d24ed9 100644
--- a/src/codegen/spirv.zig
+++ b/src/codegen/spirv.zig
@@ -669,7 +669,7 @@ pub const DeclGen = struct {
const slice = val.castTag(.slice).?.data;
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const ptr_ty = ty.slicePtrFieldType(&buf);
+ const ptr_ty = ty.slicePtrFieldType(&buf, mod);
try self.lower(ptr_ty, slice.ptr);
try self.addInt(Type.usize, slice.len);
@@ -2489,7 +2489,7 @@ pub const DeclGen = struct {
const index_id = try self.resolve(bin_op.rhs);
var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const ptr_ty = slice_ty.slicePtrFieldType(&slice_buf);
+ const ptr_ty = slice_ty.slicePtrFieldType(&slice_buf, mod);
const ptr_ty_ref = try self.resolveType(ptr_ty, .direct);
const slice_ptr = try self.extractField(ptr_ty, slice_id, 0);
@@ -2987,7 +2987,7 @@ pub const DeclGen = struct {
var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = if (payload_ty.isSlice(mod))
- payload_ty.slicePtrFieldType(&ptr_buf)
+ payload_ty.slicePtrFieldType(&ptr_buf, mod)
else
payload_ty;
diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig
index 178f9fa64c..3e4e90951e 100644
--- a/src/link/Dwarf.zig
+++ b/src/link/Dwarf.zig
@@ -278,7 +278,7 @@ pub const DeclState = struct {
var index = dbg_info_buffer.items.len;
try dbg_info_buffer.resize(index + 4);
var buf = try arena.create(Type.SlicePtrFieldTypeBuffer);
- const ptr_ty = ty.slicePtrFieldType(buf);
+ const ptr_ty = ty.slicePtrFieldType(buf, mod);
try self.addTypeRelocGlobal(atom_index, ptr_ty, @intCast(u32, index));
// DW.AT.data_member_location, DW.FORM.udata
try dbg_info_buffer.ensureUnusedCapacity(6);
diff --git a/src/type.zig b/src/type.zig
index a51ae273c1..dac12aa74e 100644
--- a/src/type.zig
+++ b/src/type.zig
@@ -2042,7 +2042,18 @@ pub const Type = struct {
else => unreachable,
},
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
- else => @panic("TODO"),
+ .ptr_type => |ptr_type| {
+ if (ptr_type.alignment != 0) {
+ return @intCast(u32, ptr_type.alignment);
+ } else if (opt_sema) |sema| {
+ const res = try ptr_type.elem_type.toType().abiAlignmentAdvanced(mod, .{ .sema = sema });
+ return res.scalar;
+ } else {
+ return (ptr_type.elem_type.toType().abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;
+ }
+ },
+ .opt_type => |child| return child.toType().ptrAlignmentAdvanced(mod, opt_sema),
+ else => unreachable,
},
}
}
@@ -3060,33 +3071,36 @@ pub const Type = struct {
pointer: Payload.Pointer,
};
- pub fn slicePtrFieldType(self: Type, buffer: *SlicePtrFieldTypeBuffer) Type {
- switch (self.tag()) {
- .pointer => {
- const payload = self.castTag(.pointer).?.data;
- assert(payload.size == .Slice);
-
- buffer.* = .{
- .pointer = .{
- .data = .{
- .pointee_type = payload.pointee_type,
- .sentinel = payload.sentinel,
- .@"align" = payload.@"align",
- .@"addrspace" = payload.@"addrspace",
- .bit_offset = payload.bit_offset,
- .host_size = payload.host_size,
- .vector_index = payload.vector_index,
- .@"allowzero" = payload.@"allowzero",
- .mutable = payload.mutable,
- .@"volatile" = payload.@"volatile",
- .size = .Many,
+ pub fn slicePtrFieldType(ty: Type, buffer: *SlicePtrFieldTypeBuffer, mod: *const Module) Type {
+ switch (ty.ip_index) {
+ .none => switch (ty.tag()) {
+ .pointer => {
+ const payload = ty.castTag(.pointer).?.data;
+ assert(payload.size == .Slice);
+
+ buffer.* = .{
+ .pointer = .{
+ .data = .{
+ .pointee_type = payload.pointee_type,
+ .sentinel = payload.sentinel,
+ .@"align" = payload.@"align",
+ .@"addrspace" = payload.@"addrspace",
+ .bit_offset = payload.bit_offset,
+ .host_size = payload.host_size,
+ .vector_index = payload.vector_index,
+ .@"allowzero" = payload.@"allowzero",
+ .mutable = payload.mutable,
+ .@"volatile" = payload.@"volatile",
+ .size = .Many,
+ },
},
- },
- };
- return Type.initPayload(&buffer.pointer.base);
- },
+ };
+ return Type.initPayload(&buffer.pointer.base);
+ },
- else => unreachable,
+ else => unreachable,
+ },
+ else => return mod.intern_pool.slicePtrType(ty.ip_index).toType(),
}
}
diff --git a/src/value.zig b/src/value.zig
index a34a022dea..f8188c64ab 100644
--- a/src/value.zig
+++ b/src/value.zig
@@ -2078,7 +2078,7 @@ pub const Value = struct {
}
var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
+ const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod);
return eqlAdvanced(a_payload.ptr, ptr_ty, b_payload.ptr, ptr_ty, mod, opt_sema);
},
@@ -2237,7 +2237,7 @@ pub const Value = struct {
}
var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
+ const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod);
const a_ptr = switch (a_ty.ptrSize(mod)) {
.Slice => a.slicePtr(),
.One => a,
@@ -2376,7 +2376,7 @@ pub const Value = struct {
.slice => {
const slice = val.castTag(.slice).?.data;
var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
+ const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod);
hash(slice.ptr, ptr_ty, hasher, mod);
hash(slice.len, Type.usize, hasher, mod);
},
@@ -2499,7 +2499,7 @@ pub const Value = struct {
.slice => {
const slice = val.castTag(.slice).?.data;
var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
+ const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod);
slice.ptr.hashUncoerced(ptr_ty, hasher, mod);
},
else => val.hashPtr(hasher, mod),