| ... | @@ -7140,12 +7140,12 @@ static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *n | ... | @@ -7140,12 +7140,12 @@ static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *n |
| 7140 | ZigType *type_entry = const_val->type; | 7140 | ZigType *type_entry = const_val->type; |
| 7141 | assert(type_has_bits(g, type_entry)); | 7141 | assert(type_has_bits(g, type_entry)); |
| 7142 | | 7142 | |
| 7143 | check: switch (const_val->special) { | 7143 | if (const_val->special == ConstValSpecialLazy && |
| | 7144 | (err = ir_resolve_lazy(g, nullptr, const_val))) |
| | 7145 | codegen_report_errors_and_exit(g); |
| | 7146 | |
| | 7147 | switch (const_val->special) { |
| 7144 | case ConstValSpecialLazy: | 7148 | case ConstValSpecialLazy: |
| 7145 | if ((err = ir_resolve_lazy(g, nullptr, const_val))) { | | |
| 7146 | codegen_report_errors_and_exit(g); | | |
| 7147 | } | | |
| 7148 | goto check; | | |
| 7149 | case ConstValSpecialRuntime: | 7149 | case ConstValSpecialRuntime: |
| 7150 | zig_unreachable(); | 7150 | zig_unreachable(); |
| 7151 | case ConstValSpecialUndef: | 7151 | case ConstValSpecialUndef: |
| ... | @@ -7222,12 +7222,26 @@ check: switch (const_val->special) { | ... | @@ -7222,12 +7222,26 @@ check: switch (const_val->special) { |
| 7222 | | 7222 | |
| 7223 | make_unnamed_struct = false; | 7223 | make_unnamed_struct = false; |
| 7224 | } | 7224 | } |
| | 7225 | |
| 7225 | LLVMValueRef fields[] = { | 7226 | LLVMValueRef fields[] = { |
| 7226 | child_val, | 7227 | child_val, |
| 7227 | maybe_val, | 7228 | maybe_val, |
| | 7229 | nullptr, |
| 7228 | }; | 7230 | }; |
| 7229 | if (make_unnamed_struct) { | 7231 | if (make_unnamed_struct) { |
| 7230 | return LLVMConstStruct(fields, 2, false); | 7232 | LLVMValueRef result = LLVMConstStruct(fields, 2, false); |
| | 7233 | uint64_t last_field_offset = LLVMOffsetOfElement(g->target_data_ref, LLVMTypeOf(result), 1); |
| | 7234 | uint64_t end_offset = last_field_offset + |
| | 7235 | LLVMStoreSizeOfType(g->target_data_ref, LLVMTypeOf(fields[1])); |
| | 7236 | uint64_t expected_sz = LLVMABISizeOfType(g->target_data_ref, get_llvm_type(g, type_entry)); |
| | 7237 | unsigned pad_sz = expected_sz - end_offset; |
| | 7238 | if (pad_sz != 0) { |
| | 7239 | fields[2] = LLVMGetUndef(LLVMArrayType(LLVMInt8Type(), pad_sz)); |
| | 7240 | result = LLVMConstStruct(fields, 3, false); |
| | 7241 | } |
| | 7242 | uint64_t actual_sz = LLVMStoreSizeOfType(g->target_data_ref, LLVMTypeOf(result)); |
| | 7243 | assert(actual_sz == expected_sz); |
| | 7244 | return result; |
| 7231 | } else { | 7245 | } else { |
| 7232 | return LLVMConstNamedStruct(get_llvm_type(g, type_entry), fields, 2); | 7246 | return LLVMConstNamedStruct(get_llvm_type(g, type_entry), fields, 2); |
| 7233 | } | 7247 | } |
| ... | @@ -7316,32 +7330,50 @@ check: switch (const_val->special) { | ... | @@ -7316,32 +7330,50 @@ check: switch (const_val->special) { |
| 7316 | continue; | 7330 | continue; |
| 7317 | } | 7331 | } |
| 7318 | ZigValue *field_val = const_val->data.x_struct.fields[i]; | 7332 | ZigValue *field_val = const_val->data.x_struct.fields[i]; |
| 7319 | assert(field_val->type != nullptr); | 7333 | ZigType *field_type = field_val->type; |
| 7320 | if ((err = ensure_const_val_repr(nullptr, g, nullptr, field_val, | 7334 | assert(field_type != nullptr); |
| 7321 | type_struct_field->type_entry))) | 7335 | if ((err = ensure_const_val_repr(nullptr, g, nullptr, field_val, field_type))) { |
| 7322 | { | | |
| 7323 | zig_unreachable(); | 7336 | zig_unreachable(); |
| 7324 | } | 7337 | } |
| 7325 | | 7338 | |
| 7326 | LLVMValueRef val = gen_const_val(g, field_val, ""); | 7339 | LLVMValueRef val = gen_const_val(g, field_val, ""); |
| 7327 | fields[type_struct_field->gen_index] = val; | 7340 | make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, field_type, val); |
| 7328 | make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, field_val->type, val); | 7341 | |
| 7329 | | 7342 | // Find the next runtime field |
| 7330 | size_t end_pad_gen_index = (i + 1 < src_field_count) ? | 7343 | size_t next_rt_gen_index = type_entry->data.structure.gen_field_count; |
| 7331 | type_entry->data.structure.fields[i + 1]->gen_index : | 7344 | size_t next_offset = type_entry->abi_size; |
| 7332 | type_entry->data.structure.gen_field_count; | 7345 | for (size_t j = i + 1; j < src_field_count; j++) { |
| 7333 | size_t next_offset = (i + 1 < src_field_count) ? | 7346 | const size_t index = type_entry->data.structure.fields[j]->gen_index; |
| 7334 | type_entry->data.structure.fields[i + 1]->offset : type_entry->abi_size; | 7347 | const size_t offset = type_entry->data.structure.fields[j]->offset; |
| 7335 | if (end_pad_gen_index != SIZE_MAX) { | 7348 | |
| 7336 | for (size_t gen_i = type_struct_field->gen_index + 1; gen_i < end_pad_gen_index; | 7349 | if (index != SIZE_MAX) { |
| 7337 | gen_i += 1) | 7350 | next_rt_gen_index = index; |
| 7338 | { | 7351 | next_offset = offset; |
| 7339 | size_t pad_bytes = next_offset - | 7352 | break; |
| 7340 | (type_struct_field->offset + type_struct_field->type_entry->abi_size); | | |
| 7341 | LLVMTypeRef llvm_array_type = LLVMArrayType(LLVMInt8Type(), pad_bytes); | | |
| 7342 | fields[gen_i] = LLVMGetUndef(llvm_array_type); | | |
| 7343 | } | 7353 | } |
| 7344 | } | 7354 | } |
| | 7355 | |
| | 7356 | // How much padding is needed to reach the next field |
| | 7357 | const size_t pad_bytes = next_offset - |
| | 7358 | (type_struct_field->offset + LLVMABISizeOfType(g->target_data_ref, LLVMTypeOf(val))); |
| | 7359 | // Catch underflow |
| | 7360 | assert((ssize_t)pad_bytes >= 0); |
| | 7361 | |
| | 7362 | if (type_struct_field->gen_index + 1 != next_rt_gen_index) { |
| | 7363 | // If there's a hole between this field and the next |
| | 7364 | // we have an alignment gap to fill |
| | 7365 | fields[type_struct_field->gen_index] = val; |
| | 7366 | fields[type_struct_field->gen_index + 1] = LLVMGetUndef(LLVMArrayType(LLVMInt8Type(), pad_bytes)); |
| | 7367 | } else if (pad_bytes != 0) { |
| | 7368 | LLVMValueRef padded_val[] = { |
| | 7369 | val, |
| | 7370 | LLVMGetUndef(LLVMArrayType(LLVMInt8Type(), pad_bytes)), |
| | 7371 | }; |
| | 7372 | fields[type_struct_field->gen_index] = LLVMConstStruct(padded_val, 2, true); |
| | 7373 | make_unnamed_struct = true; |
| | 7374 | } else { |
| | 7375 | fields[type_struct_field->gen_index] = val; |
| | 7376 | } |
| 7345 | } | 7377 | } |
| 7346 | } | 7378 | } |
| 7347 | if (make_unnamed_struct) { | 7379 | if (make_unnamed_struct) { |