| ... | @@ -242,14 +242,24 @@ struct CalcLLVMFieldIndex { | ... | @@ -242,14 +242,24 @@ struct CalcLLVMFieldIndex { |
| 242 | static void calc_llvm_field_index_add(CodeGen *g, CalcLLVMFieldIndex *calc, ZigType *ty) { | 242 | static void calc_llvm_field_index_add(CodeGen *g, CalcLLVMFieldIndex *calc, ZigType *ty) { |
| 243 | if (!type_has_bits(g, ty)) return; | 243 | if (!type_has_bits(g, ty)) return; |
| 244 | uint32_t ty_align = get_abi_alignment(g, ty); | 244 | uint32_t ty_align = get_abi_alignment(g, ty); |
| | 245 | |
| 245 | if (calc->offset % ty_align != 0) { | 246 | if (calc->offset % ty_align != 0) { |
| 246 | uint32_t llvm_align = LLVMABIAlignmentOfType(g->target_data_ref, get_llvm_type(g, ty)); | 247 | uint32_t llvm_align = LLVMABIAlignmentOfType(g->target_data_ref, get_llvm_type(g, ty)); |
| 247 | if (llvm_align >= ty_align) { | 248 | |
| 248 | ty_align = llvm_align; // llvm's padding is sufficient | 249 | // Alignment according to Zig. |
| 249 | } else if (calc->offset) { | 250 | uint32_t adj_offset = calc->offset + (ty_align - (calc->offset % ty_align)); |
| 250 | calc->field_index += 1; // zig will insert an extra padding field here | 251 | // Alignment according to LLVM. |
| 251 | } | 252 | uint32_t adj_llvm_offset = (calc->offset % llvm_align) ? |
| 252 | calc->offset += ty_align - (calc->offset % ty_align); // padding bytes | 253 | calc->offset + (llvm_align - (calc->offset % llvm_align)) : |
| | 254 | calc->offset; |
| | 255 | // Cannot under-align structure fields. |
| | 256 | assert(adj_offset >= adj_llvm_offset); |
| | 257 | |
| | 258 | // Zig will insert an extra padding field here. |
| | 259 | if (adj_offset != adj_llvm_offset) |
| | 260 | calc->field_index += 1; |
| | 261 | |
| | 262 | calc->offset = adj_offset; |
| 253 | } | 263 | } |
| 254 | calc->offset += ty->abi_size; | 264 | calc->offset += ty->abi_size; |
| 255 | calc->field_index += 1; | 265 | calc->field_index += 1; |