| ... | @@ -1245,9 +1245,10 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1245,9 +1245,10 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1245 | uint32_t gen_field_count = enum_type->data.enumeration.gen_field_count; | 1245 | uint32_t gen_field_count = enum_type->data.enumeration.gen_field_count; |
| 1246 | ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(gen_field_count); | 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 | uint64_t biggest_align_in_bits = 0; | 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 | Scope *scope = &enum_type->data.enumeration.decls_scope->base; | 1253 | Scope *scope = &enum_type->data.enumeration.decls_scope->base; |
| 1253 | ImportTableEntry *import = get_scope_import(scope); | 1254 | ImportTableEntry *import = get_scope_import(scope); |
| ... | @@ -1271,27 +1272,28 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1271,27 +1272,28 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1271 | if (!type_has_bits(field_type)) | 1272 | if (!type_has_bits(field_type)) |
| 1272 | continue; | 1273 | continue; |
| 1273 | | 1274 | |
| 1274 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref); | 1275 | uint64_t store_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 preferred_align_in_bits = 8*LLVMPreferredAlignmentOfType(g->target_data_ref, field_type->type_ref); |
| 1276 | | 1277 | |
| 1277 | assert(debug_size_in_bits > 0); | 1278 | assert(store_size_in_bits > 0); |
| 1278 | assert(debug_align_in_bits > 0); | 1279 | assert(preferred_align_in_bits > 0); |
| 1279 | | 1280 | |
| 1280 | union_inner_di_types[type_enum_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder, | 1281 | union_inner_di_types[type_enum_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder, |
| 1281 | ZigLLVMTypeToScope(enum_type->di_type), buf_ptr(type_enum_field->name), | 1282 | ZigLLVMTypeToScope(enum_type->di_type), buf_ptr(type_enum_field->name), |
| 1282 | import->di_file, (unsigned)(field_node->line + 1), | 1283 | import->di_file, (unsigned)(field_node->line + 1), |
| 1283 | debug_size_in_bits, | 1284 | store_size_in_bits, |
| 1284 | debug_align_in_bits, | 1285 | preferred_align_in_bits, |
| 1285 | 0, | 1286 | 0, |
| 1286 | 0, field_type->di_type); | 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, store_size_in_bits); |
| 1289 | | 1290 | |
| 1290 | if (!biggest_union_member || | 1291 | if (!most_aligned_union_member || |
| 1291 | debug_size_in_bits > biggest_union_member_size_in_bits) | 1292 | preferred_align_in_bits > biggest_align_in_bits) |
| 1292 | { | 1293 | { |
| 1293 | biggest_union_member = field_type; | 1294 | most_aligned_union_member = field_type; |
| 1294 | biggest_union_member_size_in_bits = debug_size_in_bits; | 1295 | biggest_align_in_bits = preferred_align_in_bits; |
| | 1296 | size_of_most_aligned_member_in_bits = store_size_in_bits; |
| 1295 | } | 1297 | } |
| 1296 | } | 1298 | } |
| 1297 | | 1299 | |
| ... | @@ -1300,27 +1302,52 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1300,27 +1302,52 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1300 | enum_type->data.enumeration.complete = true; | 1302 | enum_type->data.enumeration.complete = true; |
| 1301 | | 1303 | |
| 1302 | if (!enum_type->data.enumeration.is_invalid) { | 1304 | if (!enum_type->data.enumeration.is_invalid) { |
| 1303 | enum_type->data.enumeration.union_type = biggest_union_member; | | |
| 1304 | | | |
| 1305 | TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count); | 1305 | TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count); |
| 1306 | TypeTableEntry *tag_type_entry = create_enum_tag_type(g, enum_type, tag_int_type); | 1306 | TypeTableEntry *tag_type_entry = create_enum_tag_type(g, enum_type, tag_int_type); |
| 1307 | enum_type->data.enumeration.tag_type = tag_type_entry; | 1307 | enum_type->data.enumeration.tag_type = tag_type_entry; |
| 1308 | | 1308 | |
| 1309 | if (biggest_union_member) { | 1309 | uint64_t align_of_tag_in_bits = 8*LLVMPreferredAlignmentOfType(g->target_data_ref, tag_int_type->type_ref); |
| | 1310 | |
| | 1311 | if (most_aligned_union_member) { |
| 1310 | // create llvm type for union | 1312 | // create llvm type for union |
| 1311 | LLVMTypeRef union_element_type = biggest_union_member->type_ref; | 1313 | uint64_t padding_in_bits = biggest_size_in_bits - size_of_most_aligned_member_in_bits; |
| 1312 | LLVMTypeRef union_type_ref = LLVMStructType(&union_element_type, 1, false); | 1314 | LLVMTypeRef union_type_ref; |
| | 1315 | if (padding_in_bits > 0) { |
| | 1316 | TypeTableEntry *u8_type = get_int_type(g, false, 8); |
| | 1317 | TypeTableEntry *padding_array = get_array_type(g, u8_type, padding_in_bits / 8); |
| | 1318 | LLVMTypeRef union_element_types[] = { |
| | 1319 | most_aligned_union_member->type_ref, |
| | 1320 | padding_array->type_ref, |
| | 1321 | }; |
| | 1322 | union_type_ref = LLVMStructType(union_element_types, 2, false); |
| | 1323 | } else { |
| | 1324 | LLVMTypeRef union_element_types[] = { |
| | 1325 | most_aligned_union_member->type_ref, |
| | 1326 | }; |
| | 1327 | union_type_ref = LLVMStructType(union_element_types, 1, false); |
| | 1328 | } |
| | 1329 | enum_type->data.enumeration.union_type_ref = union_type_ref; |
| | 1330 | |
| | 1331 | assert(8*LLVMPreferredAlignmentOfType(g->target_data_ref, union_type_ref) >= biggest_align_in_bits); |
| | 1332 | assert(8*LLVMStoreSizeOfType(g->target_data_ref, union_type_ref) >= biggest_size_in_bits); |
| | 1333 | |
| | 1334 | if (align_of_tag_in_bits >= biggest_align_in_bits) { |
| | 1335 | enum_type->data.enumeration.gen_tag_index = 0; |
| | 1336 | enum_type->data.enumeration.gen_union_index = 1; |
| | 1337 | } else { |
| | 1338 | enum_type->data.enumeration.gen_union_index = 0; |
| | 1339 | enum_type->data.enumeration.gen_tag_index = 1; |
| | 1340 | } |
| 1313 | | 1341 | |
| 1314 | // create llvm type for root struct | 1342 | // create llvm type for root struct |
| 1315 | LLVMTypeRef root_struct_element_types[] = { | 1343 | LLVMTypeRef root_struct_element_types[2]; |
| 1316 | tag_type_entry->type_ref, | 1344 | root_struct_element_types[enum_type->data.enumeration.gen_tag_index] = tag_type_entry->type_ref; |
| 1317 | union_type_ref, | 1345 | root_struct_element_types[enum_type->data.enumeration.gen_union_index] = union_type_ref; |
| 1318 | }; | | |
| 1319 | LLVMStructSetBody(enum_type->type_ref, root_struct_element_types, 2, false); | 1346 | LLVMStructSetBody(enum_type->type_ref, root_struct_element_types, 2, false); |
| 1320 | | 1347 | |
| 1321 | // create debug type for tag | 1348 | // create debug type for tag |
| 1322 | uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type_entry->type_ref); | 1349 | uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type_entry->type_ref); |
| 1323 | uint64_t tag_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, tag_type_entry->type_ref); | 1350 | uint64_t tag_debug_align_in_bits = 8*LLVMPreferredAlignmentOfType(g->target_data_ref, tag_type_entry->type_ref); |
| 1324 | ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder, | 1351 | ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder, |
| 1325 | ZigLLVMTypeToScope(enum_type->di_type), "AnonEnum", | 1352 | ZigLLVMTypeToScope(enum_type->di_type), "AnonEnum", |
| 1326 | import->di_file, (unsigned)(decl_node->line + 1), | 1353 | import->di_file, (unsigned)(decl_node->line + 1), |
| ... | @@ -1331,11 +1358,12 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1331,11 +1358,12 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1331 | ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder, | 1358 | ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder, |
| 1332 | ZigLLVMTypeToScope(enum_type->di_type), "AnonUnion", | 1359 | ZigLLVMTypeToScope(enum_type->di_type), "AnonUnion", |
| 1333 | import->di_file, (unsigned)(decl_node->line + 1), | 1360 | import->di_file, (unsigned)(decl_node->line + 1), |
| 1334 | biggest_union_member_size_in_bits, biggest_align_in_bits, 0, union_inner_di_types, | 1361 | biggest_size_in_bits, biggest_align_in_bits, 0, union_inner_di_types, |
| 1335 | gen_field_count, 0, ""); | 1362 | gen_field_count, 0, ""); |
| 1336 | | 1363 | |
| 1337 | // create debug types for members of root struct | 1364 | // create debug types for members of root struct |
| 1338 | uint64_t tag_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, enum_type->type_ref, 0); | 1365 | uint64_t tag_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, enum_type->type_ref, |
| | 1366 | enum_type->data.enumeration.gen_tag_index); |
| 1339 | ZigLLVMDIType *tag_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder, | 1367 | ZigLLVMDIType *tag_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder, |
| 1340 | ZigLLVMTypeToScope(enum_type->di_type), "tag_field", | 1368 | ZigLLVMTypeToScope(enum_type->di_type), "tag_field", |
| 1341 | import->di_file, (unsigned)(decl_node->line + 1), | 1369 | import->di_file, (unsigned)(decl_node->line + 1), |
| ... | @@ -1344,21 +1372,20 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1344,21 +1372,20 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1344 | tag_offset_in_bits, | 1372 | tag_offset_in_bits, |
| 1345 | 0, tag_di_type); | 1373 | 0, tag_di_type); |
| 1346 | | 1374 | |
| 1347 | uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, enum_type->type_ref, 1); | 1375 | uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, enum_type->type_ref, |
| | 1376 | enum_type->data.enumeration.gen_union_index); |
| 1348 | ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder, | 1377 | ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder, |
| 1349 | ZigLLVMTypeToScope(enum_type->di_type), "union_field", | 1378 | ZigLLVMTypeToScope(enum_type->di_type), "union_field", |
| 1350 | import->di_file, (unsigned)(decl_node->line + 1), | 1379 | import->di_file, (unsigned)(decl_node->line + 1), |
| 1351 | biggest_union_member_size_in_bits, | 1380 | biggest_size_in_bits, |
| 1352 | biggest_align_in_bits, | 1381 | biggest_align_in_bits, |
| 1353 | union_offset_in_bits, | 1382 | union_offset_in_bits, |
| 1354 | 0, union_di_type); | 1383 | 0, union_di_type); |
| 1355 | | 1384 | |
| 1356 | // create debug type for root struct | 1385 | // create debug type for root struct |
| 1357 | ZigLLVMDIType *di_root_members[] = { | 1386 | ZigLLVMDIType *di_root_members[2]; |
| 1358 | tag_member_di_type, | 1387 | di_root_members[enum_type->data.enumeration.gen_tag_index] = tag_member_di_type; |
| 1359 | union_member_di_type, | 1388 | di_root_members[enum_type->data.enumeration.gen_union_index] = union_member_di_type; |
| 1360 | }; | | |
| 1361 | | | |
| 1362 | | 1389 | |
| 1363 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, enum_type->type_ref); | 1390 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, enum_type->type_ref); |
| 1364 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, enum_type->type_ref); | 1391 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, enum_type->type_ref); |
| ... | @@ -1378,7 +1405,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1378,7 +1405,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1378 | | 1405 | |
| 1379 | // create debug type for tag | 1406 | // create debug type for tag |
| 1380 | uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type_entry->type_ref); | 1407 | uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type_entry->type_ref); |
| 1381 | uint64_t tag_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, tag_type_entry->type_ref); | 1408 | uint64_t tag_debug_align_in_bits = 8*LLVMPreferredAlignmentOfType(g->target_data_ref, tag_type_entry->type_ref); |
| 1382 | ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder, | 1409 | ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder, |
| 1383 | ZigLLVMFileToScope(import->di_file), buf_ptr(&enum_type->name), | 1410 | ZigLLVMFileToScope(import->di_file), buf_ptr(&enum_type->name), |
| 1384 | import->di_file, (unsigned)(decl_node->line + 1), | 1411 | import->di_file, (unsigned)(decl_node->line + 1), |
| ... | @@ -2541,7 +2568,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry * | ... | @@ -2541,7 +2568,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry * |
| 2541 | if (expected_type->data.fn.is_generic != actual_type->data.fn.is_generic) { | 2568 | if (expected_type->data.fn.is_generic != actual_type->data.fn.is_generic) { |
| 2542 | return false; | 2569 | return false; |
| 2543 | } | 2570 | } |
| 2544 | if (!expected_type->data.fn.is_generic && | 2571 | if (!expected_type->data.fn.is_generic && |
| 2545 | actual_type->data.fn.fn_type_id.return_type->id != TypeTableEntryIdUnreachable && | 2572 | actual_type->data.fn.fn_type_id.return_type->id != TypeTableEntryIdUnreachable && |
| 2546 | !types_match_const_cast_only( | 2573 | !types_match_const_cast_only( |
| 2547 | expected_type->data.fn.fn_type_id.return_type, | 2574 | expected_type->data.fn.fn_type_id.return_type, |