| author | |
| committer | |
| log | a0ae575ff8aef87d2dc4134c625f3a479b484b0f |
| tree | d7442193c336b49eb5a84a477a521ab85ad7d57f |
| parent | 40feecb3e468ca9fc3b5bcbe4b0a4aa30d10f226 |
closes #3963 files changed, 36 insertions(+), 23 deletions(-)
src/all_types.hpp+3-3| ... | @@ -989,6 +989,9 @@ struct TypeTableEntryEnum { | ... | @@ -989,6 +989,9 @@ struct TypeTableEntryEnum { |
| 989 | 989 | ||
| 990 | bool zero_bits_loop_flag; | 990 | bool zero_bits_loop_flag; |
| 991 | bool zero_bits_known; | 991 | bool zero_bits_known; |
| 992 | |||
| 993 | size_t gen_union_index; | ||
| 994 | size_t gen_tag_index; | ||
| 992 | }; | 995 | }; |
| 993 | 996 | ||
| 994 | struct TypeTableEntryEnumTag { | 997 | struct TypeTableEntryEnumTag { |
| ... | @@ -2626,9 +2629,6 @@ static const size_t slice_len_index = 1; | ... | @@ -2626,9 +2629,6 @@ static const size_t slice_len_index = 1; |
| 2626 | static const size_t maybe_child_index = 0; | 2629 | static const size_t maybe_child_index = 0; |
| 2627 | static const size_t maybe_null_index = 1; | 2630 | static const size_t maybe_null_index = 1; |
| 2628 | 2631 | ||
| 2629 | static const size_t enum_gen_tag_index = 0; | ||
| 2630 | static const size_t enum_gen_union_index = 1; | ||
| 2631 | |||
| 2632 | static const size_t err_union_err_index = 0; | 2632 | static const size_t err_union_err_index = 0; |
| 2633 | static const size_t err_union_payload_index = 1; | 2633 | static const size_t err_union_payload_index = 1; |
| 2634 | 2634 |
src/analyze.cpp+21-12| ... | @@ -1306,6 +1306,8 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1306,6 +1306,8 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 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 | uint64_t align_of_tag_in_bits = 8*LLVMPreferredAlignmentOfType(g->target_data_ref, tag_int_type->type_ref); | ||
| 1310 | |||
| 1309 | if (most_aligned_union_member) { | 1311 | if (most_aligned_union_member) { |
| 1310 | // create llvm type for union | 1312 | // create llvm type for union |
| 1311 | uint64_t padding_in_bits = biggest_size_in_bits - size_of_most_aligned_member_in_bits; | 1313 | uint64_t padding_in_bits = biggest_size_in_bits - size_of_most_aligned_member_in_bits; |
| ... | @@ -1329,11 +1331,18 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1329,11 +1331,18 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1329 | assert(8*LLVMPreferredAlignmentOfType(g->target_data_ref, union_type_ref) >= biggest_align_in_bits); | 1331 | assert(8*LLVMPreferredAlignmentOfType(g->target_data_ref, union_type_ref) >= biggest_align_in_bits); |
| 1330 | assert(8*LLVMStoreSizeOfType(g->target_data_ref, union_type_ref) >= biggest_size_in_bits); | 1332 | assert(8*LLVMStoreSizeOfType(g->target_data_ref, union_type_ref) >= biggest_size_in_bits); |
| 1331 | 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 | } | ||
| 1341 | |||
| 1332 | // create llvm type for root struct | 1342 | // create llvm type for root struct |
| 1333 | LLVMTypeRef root_struct_element_types[] = { | 1343 | LLVMTypeRef root_struct_element_types[2]; |
| 1334 | tag_type_entry->type_ref, | 1344 | root_struct_element_types[enum_type->data.enumeration.gen_tag_index] = tag_type_entry->type_ref; |
| 1335 | union_type_ref, | 1345 | root_struct_element_types[enum_type->data.enumeration.gen_union_index] = union_type_ref; |
| 1336 | }; | ||
| 1337 | LLVMStructSetBody(enum_type->type_ref, root_struct_element_types, 2, false); | 1346 | LLVMStructSetBody(enum_type->type_ref, root_struct_element_types, 2, false); |
| 1338 | 1347 | ||
| 1339 | // create debug type for tag | 1348 | // create debug type for tag |
| ... | @@ -1353,7 +1362,8 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1353,7 +1362,8 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1353 | gen_field_count, 0, ""); | 1362 | gen_field_count, 0, ""); |
| 1354 | 1363 | ||
| 1355 | // create debug types for members of root struct | 1364 | // create debug types for members of root struct |
| 1356 | 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); | ||
| 1357 | ZigLLVMDIType *tag_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder, | 1367 | ZigLLVMDIType *tag_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder, |
| 1358 | ZigLLVMTypeToScope(enum_type->di_type), "tag_field", | 1368 | ZigLLVMTypeToScope(enum_type->di_type), "tag_field", |
| 1359 | import->di_file, (unsigned)(decl_node->line + 1), | 1369 | import->di_file, (unsigned)(decl_node->line + 1), |
| ... | @@ -1362,7 +1372,8 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1362,7 +1372,8 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1362 | tag_offset_in_bits, | 1372 | tag_offset_in_bits, |
| 1363 | 0, tag_di_type); | 1373 | 0, tag_di_type); |
| 1364 | 1374 | ||
| 1365 | 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); | ||
| 1366 | ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder, | 1377 | ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder, |
| 1367 | ZigLLVMTypeToScope(enum_type->di_type), "union_field", | 1378 | ZigLLVMTypeToScope(enum_type->di_type), "union_field", |
| 1368 | import->di_file, (unsigned)(decl_node->line + 1), | 1379 | import->di_file, (unsigned)(decl_node->line + 1), |
| ... | @@ -1372,11 +1383,9 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1372,11 +1383,9 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1372 | 0, union_di_type); | 1383 | 0, union_di_type); |
| 1373 | 1384 | ||
| 1374 | // create debug type for root struct | 1385 | // create debug type for root struct |
| 1375 | ZigLLVMDIType *di_root_members[] = { | 1386 | ZigLLVMDIType *di_root_members[2]; |
| 1376 | tag_member_di_type, | 1387 | di_root_members[enum_type->data.enumeration.gen_tag_index] = tag_member_di_type; |
| 1377 | union_member_di_type, | 1388 | di_root_members[enum_type->data.enumeration.gen_union_index] = union_member_di_type; |
| 1378 | }; | ||
| 1379 | |||
| 1380 | 1389 | ||
| 1381 | 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); |
| 1382 | 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); |
| ... | @@ -1396,7 +1405,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1396,7 +1405,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1396 | 1405 | ||
| 1397 | // create debug type for tag | 1406 | // create debug type for tag |
| 1398 | 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); |
| 1399 | 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); |
| 1400 | ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder, | 1409 | ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder, |
| 1401 | ZigLLVMFileToScope(import->di_file), buf_ptr(&enum_type->name), | 1410 | ZigLLVMFileToScope(import->di_file), buf_ptr(&enum_type->name), |
| 1402 | import->di_file, (unsigned)(decl_node->line + 1), | 1411 | import->di_file, (unsigned)(decl_node->line + 1), |
src/codegen.cpp+12-8| ... | @@ -2250,6 +2250,11 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa | ... | @@ -2250,6 +2250,11 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa |
| 2250 | static LLVMValueRef ir_render_enum_field_ptr(CodeGen *g, IrExecutable *executable, | 2250 | static LLVMValueRef ir_render_enum_field_ptr(CodeGen *g, IrExecutable *executable, |
| 2251 | IrInstructionEnumFieldPtr *instruction) | 2251 | IrInstructionEnumFieldPtr *instruction) |
| 2252 | { | 2252 | { |
| 2253 | TypeTableEntry *enum_ptr_type = instruction->enum_ptr->value.type; | ||
| 2254 | assert(enum_ptr_type->id == TypeTableEntryIdPointer); | ||
| 2255 | TypeTableEntry *enum_type = enum_ptr_type->data.pointer.child_type; | ||
| 2256 | assert(enum_type->id == TypeTableEntryIdEnum); | ||
| 2257 | |||
| 2253 | TypeEnumField *field = instruction->field; | 2258 | TypeEnumField *field = instruction->field; |
| 2254 | 2259 | ||
| 2255 | if (!type_has_bits(field->type_entry)) | 2260 | if (!type_has_bits(field->type_entry)) |
| ... | @@ -2257,7 +2262,7 @@ static LLVMValueRef ir_render_enum_field_ptr(CodeGen *g, IrExecutable *executabl | ... | @@ -2257,7 +2262,7 @@ static LLVMValueRef ir_render_enum_field_ptr(CodeGen *g, IrExecutable *executabl |
| 2257 | 2262 | ||
| 2258 | LLVMValueRef enum_ptr = ir_llvm_value(g, instruction->enum_ptr); | 2263 | LLVMValueRef enum_ptr = ir_llvm_value(g, instruction->enum_ptr); |
| 2259 | LLVMTypeRef field_type_ref = LLVMPointerType(field->type_entry->type_ref, 0); | 2264 | LLVMTypeRef field_type_ref = LLVMPointerType(field->type_entry->type_ref, 0); |
| 2260 | LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, enum_ptr, enum_gen_union_index, ""); | 2265 | LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, enum_ptr, enum_type->data.enumeration.gen_union_index, ""); |
| 2261 | LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, ""); | 2266 | LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, ""); |
| 2262 | 2267 | ||
| 2263 | return bitcasted_union_field_ptr; | 2268 | return bitcasted_union_field_ptr; |
| ... | @@ -3112,7 +3117,7 @@ static LLVMValueRef ir_render_enum_tag(CodeGen *g, IrExecutable *executable, IrI | ... | @@ -3112,7 +3117,7 @@ static LLVMValueRef ir_render_enum_tag(CodeGen *g, IrExecutable *executable, IrI |
| 3112 | if (enum_type->data.enumeration.gen_field_count == 0) | 3117 | if (enum_type->data.enumeration.gen_field_count == 0) |
| 3113 | return enum_val; | 3118 | return enum_val; |
| 3114 | 3119 | ||
| 3115 | LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, enum_val, enum_gen_tag_index, ""); | 3120 | LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, enum_val, enum_type->data.enumeration.gen_tag_index, ""); |
| 3116 | return get_handle_value(g, tag_field_ptr, tag_type, false); | 3121 | return get_handle_value(g, tag_field_ptr, tag_type, false); |
| 3117 | } | 3122 | } |
| 3118 | 3123 | ||
| ... | @@ -3127,13 +3132,13 @@ static LLVMValueRef ir_render_init_enum(CodeGen *g, IrExecutable *executable, Ir | ... | @@ -3127,13 +3132,13 @@ static LLVMValueRef ir_render_init_enum(CodeGen *g, IrExecutable *executable, Ir |
| 3127 | 3132 | ||
| 3128 | LLVMValueRef tmp_struct_ptr = instruction->tmp_ptr; | 3133 | LLVMValueRef tmp_struct_ptr = instruction->tmp_ptr; |
| 3129 | 3134 | ||
| 3130 | LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, enum_gen_tag_index, ""); | 3135 | LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, enum_type->data.enumeration.gen_tag_index, ""); |
| 3131 | LLVMBuildStore(g->builder, tag_value, tag_field_ptr); | 3136 | LLVMBuildStore(g->builder, tag_value, tag_field_ptr); |
| 3132 | 3137 | ||
| 3133 | TypeTableEntry *union_val_type = instruction->field->type_entry; | 3138 | TypeTableEntry *union_val_type = instruction->field->type_entry; |
| 3134 | if (type_has_bits(union_val_type)) { | 3139 | if (type_has_bits(union_val_type)) { |
| 3135 | LLVMValueRef new_union_val = ir_llvm_value(g, instruction->init_value); | 3140 | LLVMValueRef new_union_val = ir_llvm_value(g, instruction->init_value); |
| 3136 | LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, enum_gen_union_index, ""); | 3141 | LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, enum_type->data.enumeration.gen_union_index, ""); |
| 3137 | LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, | 3142 | LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, |
| 3138 | LLVMPointerType(union_val_type->type_ref, 0), ""); | 3143 | LLVMPointerType(union_val_type->type_ref, 0), ""); |
| 3139 | 3144 | ||
| ... | @@ -3687,10 +3692,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { | ... | @@ -3687,10 +3692,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3687 | } else { | 3692 | } else { |
| 3688 | union_value = LLVMGetUndef(union_type_ref); | 3693 | union_value = LLVMGetUndef(union_type_ref); |
| 3689 | } | 3694 | } |
| 3690 | LLVMValueRef fields[] = { | 3695 | LLVMValueRef fields[2]; |
| 3691 | tag_value, | 3696 | fields[type_entry->data.enumeration.gen_tag_index] = tag_value; |
| 3692 | union_value, | 3697 | fields[type_entry->data.enumeration.gen_union_index] = union_value; |
| 3693 | }; | ||
| 3694 | return LLVMConstStruct(fields, 2, false); | 3698 | return LLVMConstStruct(fields, 2, false); |
| 3695 | } | 3699 | } |
| 3696 | } | 3700 | } |