| ... | ... | @@ -2647,7 +2647,7 @@ pub const FuncGen = struct { |
| 2647 | 2647 | switch (struct_ty.zigTypeTag()) { |
| 2648 | 2648 | .Struct => { |
| 2649 | 2649 | var ptr_ty_buf: Type.Payload.Pointer = undefined; |
| 2650 | | const llvm_field_index = llvmFieldIndex(struct_ty, field_index, target, &ptr_ty_buf); |
| 2650 | const llvm_field_index = llvmFieldIndex(struct_ty, field_index, target, &ptr_ty_buf).?; |
| 2651 | 2651 | const field_ptr = self.builder.buildStructGEP(struct_llvm_val, llvm_field_index, ""); |
| 2652 | 2652 | const field_ptr_ty = Type.initPayload(&ptr_ty_buf.base); |
| 2653 | 2653 | return self.load(field_ptr, field_ptr_ty); |
| ... | ... | @@ -4354,8 +4354,18 @@ pub const FuncGen = struct { |
| 4354 | 4354 | .Struct => { |
| 4355 | 4355 | const target = self.dg.module.getTarget(); |
| 4356 | 4356 | var ty_buf: Type.Payload.Pointer = undefined; |
| 4357 | | const llvm_field_index = llvmFieldIndex(struct_ty, field_index, target, &ty_buf); |
| 4358 | | return self.builder.buildStructGEP(struct_ptr, llvm_field_index, ""); |
| 4357 | if (llvmFieldIndex(struct_ty, field_index, target, &ty_buf)) |llvm_field_index| { |
| 4358 | return self.builder.buildStructGEP(struct_ptr, llvm_field_index, ""); |
| 4359 | } else { |
| 4360 | // If we found no index then this means this is a zero sized field at the |
| 4361 | // end of the struct. Treat our struct pointer as an array of two and get |
| 4362 | // the index to the element at index `1` to get a pointer to the end of |
| 4363 | // the struct. |
| 4364 | const llvm_usize = try self.dg.llvmType(Type.usize); |
| 4365 | const llvm_index = llvm_usize.constInt(1, .False); |
| 4366 | const indices: [1]*const llvm.Value = .{llvm_index}; |
| 4367 | return self.builder.buildInBoundsGEP(struct_ptr, &indices, indices.len, ""); |
| 4368 | } |
| 4359 | 4369 | }, |
| 4360 | 4370 | .Union => return self.unionFieldPtr(inst, struct_ptr, struct_ty, field_index), |
| 4361 | 4371 | else => unreachable, |
| ... | ... | @@ -4750,32 +4760,37 @@ fn toLlvmCallConv(cc: std.builtin.CallingConvention, target: std.Target) llvm.Ca |
| 4750 | 4760 | }; |
| 4751 | 4761 | } |
| 4752 | 4762 | |
| 4753 | | /// Take into account 0 bit fields. |
| 4763 | /// Take into account 0 bit fields. Returns null if an llvm field could not be found. This only |
| 4764 | /// happends if you want the field index of a zero sized field at the end of the struct. |
| 4754 | 4765 | fn llvmFieldIndex( |
| 4755 | 4766 | ty: Type, |
| 4756 | 4767 | field_index: u32, |
| 4757 | 4768 | target: std.Target, |
| 4758 | 4769 | ptr_pl_buf: *Type.Payload.Pointer, |
| 4759 | | ) c_uint { |
| 4770 | ) ?c_uint { |
| 4760 | 4771 | const struct_obj = ty.castTag(.@"struct").?.data; |
| 4761 | 4772 | if (struct_obj.layout != .Packed) { |
| 4762 | 4773 | var llvm_field_index: c_uint = 0; |
| 4763 | 4774 | for (struct_obj.fields.values()) |field, i| { |
| 4764 | | if (!field.ty.hasCodeGenBits()) continue; |
| 4765 | | |
| 4766 | | if (i == field_index) { |
| 4767 | | ptr_pl_buf.* = .{ |
| 4768 | | .data = .{ |
| 4769 | | .pointee_type = field.ty, |
| 4770 | | .@"align" = field.normalAlignment(target), |
| 4771 | | .@"addrspace" = .generic, |
| 4772 | | }, |
| 4773 | | }; |
| 4774 | | return llvm_field_index; |
| 4775 | if (!field.ty.hasCodeGenBits()) |
| 4776 | continue; |
| 4777 | if (field_index > i) { |
| 4778 | llvm_field_index += 1; |
| 4779 | continue; |
| 4775 | 4780 | } |
| 4776 | | llvm_field_index += 1; |
| 4781 | |
| 4782 | ptr_pl_buf.* = .{ |
| 4783 | .data = .{ |
| 4784 | .pointee_type = field.ty, |
| 4785 | .@"align" = field.normalAlignment(target), |
| 4786 | .@"addrspace" = .generic, |
| 4787 | }, |
| 4788 | }; |
| 4789 | return llvm_field_index; |
| 4790 | } else { |
| 4791 | // We did not find an llvm field that corrispons to this zig field. |
| 4792 | return null; |
| 4777 | 4793 | } |
| 4778 | | unreachable; |
| 4779 | 4794 | } |
| 4780 | 4795 | |
| 4781 | 4796 | // Our job here is to return the host integer field index. |
| ... | ... | @@ -4784,7 +4799,8 @@ fn llvmFieldIndex( |
| 4784 | 4799 | var running_bits: u16 = 0; |
| 4785 | 4800 | var llvm_field_index: c_uint = 0; |
| 4786 | 4801 | for (struct_obj.fields.values()) |field, i| { |
| 4787 | | if (!field.ty.hasCodeGenBits()) continue; |
| 4802 | if (!field.ty.hasCodeGenBits()) |
| 4803 | continue; |
| 4788 | 4804 | |
| 4789 | 4805 | const field_align = field.packedAlignment(); |
| 4790 | 4806 | if (field_align == 0) { |