Commit bc3b56f957
Changed files (1)
src
codegen
src/codegen/llvm.zig
@@ -3789,10 +3789,7 @@ pub const DeclGen = struct {
fn lowerIntAsPtr(dg: *DeclGen, val: Value) Error!*llvm.Value {
switch (dg.module.intern_pool.indexToKey(val.toIntern())) {
- .undef => {
- const llvm_usize = try dg.lowerType(Type.usize);
- return llvm_usize.getUndef();
- },
+ .undef => return dg.context.pointerType(0).getUndef(),
.int => {
var bigint_space: Value.BigIntSpace = undefined;
const bigint = val.toBigInt(&bigint_space, dg.module);
@@ -3847,141 +3844,137 @@ pub const DeclGen = struct {
fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value {
const mod = dg.module;
const target = mod.getTarget();
- return switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) {
- .int => dg.lowerIntAsPtr(ptr_val),
- .ptr => |ptr| switch (ptr.addr) {
- .decl => |decl| dg.lowerParentPtrDecl(ptr_val, decl),
- .mut_decl => |mut_decl| dg.lowerParentPtrDecl(ptr_val, mut_decl.decl),
- .int => |int| dg.lowerIntAsPtr(int.toValue()),
- .eu_payload => |eu_ptr| {
- const parent_llvm_ptr = try dg.lowerParentPtr(eu_ptr.toValue(), true);
-
- const eu_ty = mod.intern_pool.typeOf(eu_ptr).toType().childType(mod);
- const payload_ty = eu_ty.errorUnionPayload(mod);
- if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
- // In this case, we represent pointer to error union the same as pointer
- // to the payload.
- return parent_llvm_ptr;
- }
+ return switch (mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr) {
+ .decl => |decl| dg.lowerParentPtrDecl(ptr_val, decl),
+ .mut_decl => |mut_decl| dg.lowerParentPtrDecl(ptr_val, mut_decl.decl),
+ .int => |int| dg.lowerIntAsPtr(int.toValue()),
+ .eu_payload => |eu_ptr| {
+ const parent_llvm_ptr = try dg.lowerParentPtr(eu_ptr.toValue(), true);
+
+ const eu_ty = mod.intern_pool.typeOf(eu_ptr).toType().childType(mod);
+ const payload_ty = eu_ty.errorUnionPayload(mod);
+ if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
+ // In this case, we represent pointer to error union the same as pointer
+ // to the payload.
+ return parent_llvm_ptr;
+ }
- const payload_offset: u8 = if (payload_ty.abiAlignment(mod) > Type.anyerror.abiSize(mod)) 2 else 1;
- const llvm_u32 = dg.context.intType(32);
- const indices: [2]*llvm.Value = .{
- llvm_u32.constInt(0, .False),
- llvm_u32.constInt(payload_offset, .False),
- };
- const eu_llvm_ty = try dg.lowerType(eu_ty);
- return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
- },
- .opt_payload => |opt_ptr| {
- const parent_llvm_ptr = try dg.lowerParentPtr(opt_ptr.toValue(), true);
+ const payload_offset: u8 = if (payload_ty.abiAlignment(mod) > Type.anyerror.abiSize(mod)) 2 else 1;
+ const llvm_u32 = dg.context.intType(32);
+ const indices: [2]*llvm.Value = .{
+ llvm_u32.constInt(0, .False),
+ llvm_u32.constInt(payload_offset, .False),
+ };
+ const eu_llvm_ty = try dg.lowerType(eu_ty);
+ return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
+ },
+ .opt_payload => |opt_ptr| {
+ const parent_llvm_ptr = try dg.lowerParentPtr(opt_ptr.toValue(), true);
- const opt_ty = mod.intern_pool.typeOf(opt_ptr).toType().childType(mod);
- const payload_ty = opt_ty.optionalChild(mod);
- if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or
- payload_ty.optionalReprIsPayload(mod))
- {
- // In this case, we represent pointer to optional the same as pointer
- // to the payload.
- return parent_llvm_ptr;
- }
+ const opt_ty = mod.intern_pool.typeOf(opt_ptr).toType().childType(mod);
+ const payload_ty = opt_ty.optionalChild(mod);
+ if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or
+ payload_ty.optionalReprIsPayload(mod))
+ {
+ // In this case, we represent pointer to optional the same as pointer
+ // to the payload.
+ return parent_llvm_ptr;
+ }
- const llvm_u32 = dg.context.intType(32);
- const indices: [2]*llvm.Value = .{
- llvm_u32.constInt(0, .False),
- llvm_u32.constInt(0, .False),
- };
- const opt_llvm_ty = try dg.lowerType(opt_ty);
- return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
- },
- .comptime_field => unreachable,
- .elem => |elem_ptr| {
- const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.base.toValue(), true);
+ const llvm_u32 = dg.context.intType(32);
+ const indices: [2]*llvm.Value = .{
+ llvm_u32.constInt(0, .False),
+ llvm_u32.constInt(0, .False),
+ };
+ const opt_llvm_ty = try dg.lowerType(opt_ty);
+ return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
+ },
+ .comptime_field => unreachable,
+ .elem => |elem_ptr| {
+ const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.base.toValue(), true);
- const llvm_usize = try dg.lowerType(Type.usize);
- const indices: [1]*llvm.Value = .{
- llvm_usize.constInt(elem_ptr.index, .False),
- };
- const elem_ty = mod.intern_pool.typeOf(elem_ptr.base).toType().elemType2(mod);
- const elem_llvm_ty = try dg.lowerType(elem_ty);
- return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
- },
- .field => |field_ptr| {
- const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.base.toValue(), byte_aligned);
- const parent_ty = mod.intern_pool.typeOf(field_ptr.base).toType().childType(mod);
-
- const field_index = @intCast(u32, field_ptr.index);
- const llvm_u32 = dg.context.intType(32);
- switch (parent_ty.zigTypeTag(mod)) {
- .Union => {
- if (parent_ty.containerLayout(mod) == .Packed) {
- return parent_llvm_ptr;
- }
+ const llvm_usize = try dg.lowerType(Type.usize);
+ const indices: [1]*llvm.Value = .{
+ llvm_usize.constInt(elem_ptr.index, .False),
+ };
+ const elem_ty = mod.intern_pool.typeOf(elem_ptr.base).toType().elemType2(mod);
+ const elem_llvm_ty = try dg.lowerType(elem_ty);
+ return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
+ },
+ .field => |field_ptr| {
+ const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.base.toValue(), byte_aligned);
+ const parent_ty = mod.intern_pool.typeOf(field_ptr.base).toType().childType(mod);
+
+ const field_index = @intCast(u32, field_ptr.index);
+ const llvm_u32 = dg.context.intType(32);
+ switch (parent_ty.zigTypeTag(mod)) {
+ .Union => {
+ if (parent_ty.containerLayout(mod) == .Packed) {
+ return parent_llvm_ptr;
+ }
- const layout = parent_ty.unionGetLayout(mod);
- if (layout.payload_size == 0) {
- // In this case a pointer to the union and a pointer to any
- // (void) payload is the same.
- return parent_llvm_ptr;
- }
- const llvm_pl_index = if (layout.tag_size == 0)
- 0
- else
- @boolToInt(layout.tag_align >= layout.payload_align);
- const indices: [2]*llvm.Value = .{
- llvm_u32.constInt(0, .False),
- llvm_u32.constInt(llvm_pl_index, .False),
+ const layout = parent_ty.unionGetLayout(mod);
+ if (layout.payload_size == 0) {
+ // In this case a pointer to the union and a pointer to any
+ // (void) payload is the same.
+ return parent_llvm_ptr;
+ }
+ const llvm_pl_index = if (layout.tag_size == 0)
+ 0
+ else
+ @boolToInt(layout.tag_align >= layout.payload_align);
+ const indices: [2]*llvm.Value = .{
+ llvm_u32.constInt(0, .False),
+ llvm_u32.constInt(llvm_pl_index, .False),
+ };
+ const parent_llvm_ty = try dg.lowerType(parent_ty);
+ return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
+ },
+ .Struct => {
+ if (parent_ty.containerLayout(mod) == .Packed) {
+ if (!byte_aligned) return parent_llvm_ptr;
+ const llvm_usize = dg.context.intType(target.ptrBitWidth());
+ const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize);
+ // count bits of fields before this one
+ const prev_bits = b: {
+ var b: usize = 0;
+ for (parent_ty.structFields(mod).values()[0..field_index]) |field| {
+ if (field.is_comptime or !field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
+ b += @intCast(usize, field.ty.bitSize(mod));
+ }
+ break :b b;
};
- const parent_llvm_ty = try dg.lowerType(parent_ty);
- return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
- },
- .Struct => {
- if (parent_ty.containerLayout(mod) == .Packed) {
- if (!byte_aligned) return parent_llvm_ptr;
- const llvm_usize = dg.context.intType(target.ptrBitWidth());
- const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize);
- // count bits of fields before this one
- const prev_bits = b: {
- var b: usize = 0;
- for (parent_ty.structFields(mod).values()[0..field_index]) |field| {
- if (field.is_comptime or !field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
- b += @intCast(usize, field.ty.bitSize(mod));
- }
- break :b b;
- };
- const byte_offset = llvm_usize.constInt(prev_bits / 8, .False);
- const field_addr = base_addr.constAdd(byte_offset);
- const final_llvm_ty = dg.context.pointerType(0);
- return field_addr.constIntToPtr(final_llvm_ty);
- }
+ const byte_offset = llvm_usize.constInt(prev_bits / 8, .False);
+ const field_addr = base_addr.constAdd(byte_offset);
+ const final_llvm_ty = dg.context.pointerType(0);
+ return field_addr.constIntToPtr(final_llvm_ty);
+ }
- const parent_llvm_ty = try dg.lowerType(parent_ty);
- if (llvmField(parent_ty, field_index, mod)) |llvm_field| {
- const indices: [2]*llvm.Value = .{
- llvm_u32.constInt(0, .False),
- llvm_u32.constInt(llvm_field.index, .False),
- };
- return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
- } else {
- const llvm_index = llvm_u32.constInt(@boolToInt(parent_ty.hasRuntimeBitsIgnoreComptime(mod)), .False);
- const indices: [1]*llvm.Value = .{llvm_index};
- return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
- }
- },
- .Pointer => {
- assert(parent_ty.isSlice(mod));
+ const parent_llvm_ty = try dg.lowerType(parent_ty);
+ if (llvmField(parent_ty, field_index, mod)) |llvm_field| {
const indices: [2]*llvm.Value = .{
llvm_u32.constInt(0, .False),
- llvm_u32.constInt(field_index, .False),
+ llvm_u32.constInt(llvm_field.index, .False),
};
- const parent_llvm_ty = try dg.lowerType(parent_ty);
return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
- },
- else => unreachable,
- }
- },
+ } else {
+ const llvm_index = llvm_u32.constInt(@boolToInt(parent_ty.hasRuntimeBitsIgnoreComptime(mod)), .False);
+ const indices: [1]*llvm.Value = .{llvm_index};
+ return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
+ }
+ },
+ .Pointer => {
+ assert(parent_ty.isSlice(mod));
+ const indices: [2]*llvm.Value = .{
+ llvm_u32.constInt(0, .False),
+ llvm_u32.constInt(field_index, .False),
+ };
+ const parent_llvm_ty = try dg.lowerType(parent_ty);
+ return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
+ },
+ else => unreachable,
+ }
},
- else => unreachable,
};
}