| ... | ... | @@ -1245,9 +1245,10 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1245 | 1245 | uint32_t gen_field_count = enum_type->data.enumeration.gen_field_count; |
| 1246 | 1246 | ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(gen_field_count); |
| 1247 | 1247 | |
| 1248 | | TypeTableEntry *biggest_union_member = nullptr; |
| 1248 | TypeTableEntry *most_aligned_union_member = nullptr; |
| 1249 | uint64_t size_of_most_aligned_member_in_bits = 0; |
| 1249 | 1250 | uint64_t biggest_align_in_bits = 0; |
| 1250 | | uint64_t biggest_union_member_size_in_bits = 0; |
| 1251 | uint64_t biggest_size_in_bits = 0; |
| 1251 | 1252 | |
| 1252 | 1253 | Scope *scope = &enum_type->data.enumeration.decls_scope->base; |
| 1253 | 1254 | ImportTableEntry *import = get_scope_import(scope); |
| ... | ... | @@ -1272,7 +1273,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1272 | 1273 | continue; |
| 1273 | 1274 | |
| 1274 | 1275 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref); |
| 1275 | | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, field_type->type_ref); |
| 1276 | uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, field_type->type_ref); |
| 1276 | 1277 | |
| 1277 | 1278 | assert(debug_size_in_bits > 0); |
| 1278 | 1279 | assert(debug_align_in_bits > 0); |
| ... | ... | @@ -1285,13 +1286,14 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1285 | 1286 | 0, |
| 1286 | 1287 | 0, field_type->di_type); |
| 1287 | 1288 | |
| 1288 | | biggest_align_in_bits = max(biggest_align_in_bits, debug_align_in_bits); |
| 1289 | biggest_size_in_bits = max(biggest_size_in_bits, debug_size_in_bits); |
| 1289 | 1290 | |
| 1290 | | if (!biggest_union_member || |
| 1291 | | debug_size_in_bits > biggest_union_member_size_in_bits) |
| 1291 | if (!most_aligned_union_member || |
| 1292 | debug_align_in_bits > biggest_align_in_bits) |
| 1292 | 1293 | { |
| 1293 | | biggest_union_member = field_type; |
| 1294 | | biggest_union_member_size_in_bits = debug_size_in_bits; |
| 1294 | most_aligned_union_member = field_type; |
| 1295 | biggest_align_in_bits = debug_align_in_bits; |
| 1296 | size_of_most_aligned_member_in_bits = debug_size_in_bits; |
| 1295 | 1297 | } |
| 1296 | 1298 | } |
| 1297 | 1299 | |
| ... | ... | @@ -1300,16 +1302,34 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1300 | 1302 | enum_type->data.enumeration.complete = true; |
| 1301 | 1303 | |
| 1302 | 1304 | if (!enum_type->data.enumeration.is_invalid) { |
| 1303 | | enum_type->data.enumeration.union_type = biggest_union_member; |
| 1304 | | |
| 1305 | 1305 | TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count); |
| 1306 | 1306 | TypeTableEntry *tag_type_entry = create_enum_tag_type(g, enum_type, tag_int_type); |
| 1307 | 1307 | enum_type->data.enumeration.tag_type = tag_type_entry; |
| 1308 | 1308 | |
| 1309 | | if (biggest_union_member) { |
| 1309 | if (most_aligned_union_member) { |
| 1310 | 1310 | // create llvm type for union |
| 1311 | | LLVMTypeRef union_element_type = biggest_union_member->type_ref; |
| 1312 | | LLVMTypeRef union_type_ref = LLVMStructType(&union_element_type, 1, false); |
| 1311 | uint64_t padding_in_bits = biggest_size_in_bits - size_of_most_aligned_member_in_bits; |
| 1312 | LLVMTypeRef union_type_ref; |
| 1313 | if (padding_in_bits > 0) { |
| 1314 | TypeTableEntry *u8_type = get_int_type(g, false, 8); |
| 1315 | TypeTableEntry *padding_array = get_array_type(g, u8_type, padding_in_bits / 8); |
| 1316 | LLVMTypeRef union_element_types[] = { |
| 1317 | most_aligned_union_member->type_ref, |
| 1318 | padding_array->type_ref, |
| 1319 | }; |
| 1320 | union_type_ref = LLVMStructType(union_element_types, 2, false); |
| 1321 | } else { |
| 1322 | LLVMTypeRef union_element_types[] = { |
| 1323 | most_aligned_union_member->type_ref, |
| 1324 | }; |
| 1325 | union_type_ref = LLVMStructType(union_element_types, 1, false); |
| 1326 | } |
| 1327 | enum_type->data.enumeration.union_type_ref = union_type_ref; |
| 1328 | |
| 1329 | assert(8*LLVMABIAlignmentOfType(g->target_data_ref, union_type_ref) >= |
| 1330 | biggest_align_in_bits); |
| 1331 | assert(8*LLVMABISizeOfType(g->target_data_ref, union_type_ref) >= |
| 1332 | biggest_size_in_bits); |
| 1313 | 1333 | |
| 1314 | 1334 | // create llvm type for root struct |
| 1315 | 1335 | LLVMTypeRef root_struct_element_types[] = { |
| ... | ... | @@ -1331,7 +1351,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1331 | 1351 | ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder, |
| 1332 | 1352 | ZigLLVMTypeToScope(enum_type->di_type), "AnonUnion", |
| 1333 | 1353 | import->di_file, (unsigned)(decl_node->line + 1), |
| 1334 | | biggest_union_member_size_in_bits, biggest_align_in_bits, 0, union_inner_di_types, |
| 1354 | biggest_size_in_bits, biggest_align_in_bits, 0, union_inner_di_types, |
| 1335 | 1355 | gen_field_count, 0, ""); |
| 1336 | 1356 | |
| 1337 | 1357 | // create debug types for members of root struct |
| ... | ... | @@ -1348,7 +1368,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1348 | 1368 | ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder, |
| 1349 | 1369 | ZigLLVMTypeToScope(enum_type->di_type), "union_field", |
| 1350 | 1370 | import->di_file, (unsigned)(decl_node->line + 1), |
| 1351 | | biggest_union_member_size_in_bits, |
| 1371 | biggest_size_in_bits, |
| 1352 | 1372 | biggest_align_in_bits, |
| 1353 | 1373 | union_offset_in_bits, |
| 1354 | 1374 | 0, union_di_type); |
| ... | ... | @@ -2541,7 +2561,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry * |
| 2541 | 2561 | if (expected_type->data.fn.is_generic != actual_type->data.fn.is_generic) { |
| 2542 | 2562 | return false; |
| 2543 | 2563 | } |
| 2544 | | if (!expected_type->data.fn.is_generic && |
| 2564 | if (!expected_type->data.fn.is_generic && |
| 2545 | 2565 | actual_type->data.fn.fn_type_id.return_type->id != TypeTableEntryIdUnreachable && |
| 2546 | 2566 | !types_match_const_cast_only( |
| 2547 | 2567 | expected_type->data.fn.fn_type_id.return_type, |