| ... | @@ -20,6 +20,10 @@ static const size_t default_backward_branch_quota = 1000; | ... | @@ -20,6 +20,10 @@ static const size_t default_backward_branch_quota = 1000; |
| 20 | static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type); | 20 | static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type); |
| 21 | static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type); | 21 | static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type); |
| 22 | | 22 | |
| | 23 | static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type); |
| | 24 | static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type); |
| | 25 | static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type); |
| | 26 | |
| 23 | AstNode *first_executing_node(AstNode *node) { | 27 | AstNode *first_executing_node(AstNode *node) { |
| 24 | switch (node->type) { | 28 | switch (node->type) { |
| 25 | case NodeTypeFnCallExpr: | 29 | case NodeTypeFnCallExpr: |
| ... | @@ -257,6 +261,44 @@ bool type_is_complete(TypeTableEntry *type_entry) { | ... | @@ -257,6 +261,44 @@ bool type_is_complete(TypeTableEntry *type_entry) { |
| 257 | zig_unreachable(); | 261 | zig_unreachable(); |
| 258 | } | 262 | } |
| 259 | | 263 | |
| | 264 | bool type_has_zero_bits_known(TypeTableEntry *type_entry) { |
| | 265 | switch (type_entry->id) { |
| | 266 | case TypeTableEntryIdInvalid: |
| | 267 | case TypeTableEntryIdVar: |
| | 268 | zig_unreachable(); |
| | 269 | case TypeTableEntryIdStruct: |
| | 270 | return type_entry->data.structure.zero_bits_known; |
| | 271 | case TypeTableEntryIdEnum: |
| | 272 | return type_entry->data.enumeration.zero_bits_known; |
| | 273 | case TypeTableEntryIdUnion: |
| | 274 | return type_entry->data.unionation.zero_bits_known; |
| | 275 | case TypeTableEntryIdMetaType: |
| | 276 | case TypeTableEntryIdVoid: |
| | 277 | case TypeTableEntryIdBool: |
| | 278 | case TypeTableEntryIdUnreachable: |
| | 279 | case TypeTableEntryIdInt: |
| | 280 | case TypeTableEntryIdFloat: |
| | 281 | case TypeTableEntryIdPointer: |
| | 282 | case TypeTableEntryIdArray: |
| | 283 | case TypeTableEntryIdNumLitFloat: |
| | 284 | case TypeTableEntryIdNumLitInt: |
| | 285 | case TypeTableEntryIdUndefLit: |
| | 286 | case TypeTableEntryIdNullLit: |
| | 287 | case TypeTableEntryIdMaybe: |
| | 288 | case TypeTableEntryIdErrorUnion: |
| | 289 | case TypeTableEntryIdPureError: |
| | 290 | case TypeTableEntryIdFn: |
| | 291 | case TypeTableEntryIdTypeDecl: |
| | 292 | case TypeTableEntryIdNamespace: |
| | 293 | case TypeTableEntryIdBlock: |
| | 294 | case TypeTableEntryIdBoundFn: |
| | 295 | case TypeTableEntryIdEnumTag: |
| | 296 | return true; |
| | 297 | } |
| | 298 | zig_unreachable(); |
| | 299 | } |
| | 300 | |
| | 301 | |
| 260 | uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry) { | 302 | uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry) { |
| 261 | if (type_has_bits(type_entry)) { | 303 | if (type_has_bits(type_entry)) { |
| 262 | return LLVMStoreSizeOfType(g->target_data_ref, type_entry->type_ref); | 304 | return LLVMStoreSizeOfType(g->target_data_ref, type_entry->type_ref); |
| ... | @@ -475,13 +517,14 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t | ... | @@ -475,13 +517,14 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t |
| 475 | return entry; | 517 | return entry; |
| 476 | } else { | 518 | } else { |
| 477 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray); | 519 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray); |
| 478 | entry->type_ref = child_type->type_ref ? LLVMArrayType(child_type->type_ref, array_size) : nullptr; | | |
| 479 | entry->zero_bits = (array_size == 0) || child_type->zero_bits; | 520 | entry->zero_bits = (array_size == 0) || child_type->zero_bits; |
| 480 | | 521 | |
| 481 | buf_resize(&entry->name, 0); | 522 | buf_resize(&entry->name, 0); |
| 482 | buf_appendf(&entry->name, "[%" PRIu64 "]%s", array_size, buf_ptr(&child_type->name)); | 523 | buf_appendf(&entry->name, "[%" PRIu64 "]%s", array_size, buf_ptr(&child_type->name)); |
| 483 | | 524 | |
| 484 | if (!entry->zero_bits) { | 525 | if (!entry->zero_bits) { |
| | 526 | entry->type_ref = child_type->type_ref ? LLVMArrayType(child_type->type_ref, array_size) : nullptr; |
| | 527 | |
| 485 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); | 528 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); |
| 486 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref); | 529 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref); |
| 487 | | 530 | |
| ... | @@ -507,14 +550,21 @@ static void slice_type_common_init(CodeGen *g, TypeTableEntry *child_type, | ... | @@ -507,14 +550,21 @@ static void slice_type_common_init(CodeGen *g, TypeTableEntry *child_type, |
| 507 | entry->data.structure.src_field_count = element_count; | 550 | entry->data.structure.src_field_count = element_count; |
| 508 | entry->data.structure.gen_field_count = element_count; | 551 | entry->data.structure.gen_field_count = element_count; |
| 509 | entry->data.structure.fields = allocate<TypeStructField>(element_count); | 552 | entry->data.structure.fields = allocate<TypeStructField>(element_count); |
| 510 | entry->data.structure.fields[0].name = buf_create_from_str("ptr"); | 553 | entry->data.structure.fields[slice_ptr_index].name = buf_create_from_str("ptr"); |
| 511 | entry->data.structure.fields[0].type_entry = pointer_type; | 554 | entry->data.structure.fields[slice_ptr_index].type_entry = pointer_type; |
| 512 | entry->data.structure.fields[0].src_index = 0; | 555 | entry->data.structure.fields[slice_ptr_index].src_index = slice_ptr_index; |
| 513 | entry->data.structure.fields[0].gen_index = 0; | 556 | entry->data.structure.fields[slice_ptr_index].gen_index = 0; |
| 514 | entry->data.structure.fields[1].name = buf_create_from_str("len"); | 557 | entry->data.structure.fields[slice_len_index].name = buf_create_from_str("len"); |
| 515 | entry->data.structure.fields[1].type_entry = g->builtin_types.entry_usize; | 558 | entry->data.structure.fields[slice_len_index].type_entry = g->builtin_types.entry_usize; |
| 516 | entry->data.structure.fields[1].src_index = 1; | 559 | entry->data.structure.fields[slice_len_index].src_index = slice_len_index; |
| 517 | entry->data.structure.fields[1].gen_index = 1; | 560 | entry->data.structure.fields[slice_len_index].gen_index = 1; |
| | 561 | |
| | 562 | assert(type_has_zero_bits_known(child_type)); |
| | 563 | if (child_type->zero_bits) { |
| | 564 | entry->data.structure.gen_field_count = 1; |
| | 565 | entry->data.structure.fields[slice_ptr_index].gen_index = SIZE_MAX; |
| | 566 | entry->data.structure.fields[slice_len_index].gen_index = 0; |
| | 567 | } |
| 518 | } | 568 | } |
| 519 | | 569 | |
| 520 | TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_const) { | 570 | TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_const) { |
| ... | @@ -535,6 +585,7 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c | ... | @@ -535,6 +585,7 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c |
| 535 | entry->type_ref = var_peer->type_ref; | 585 | entry->type_ref = var_peer->type_ref; |
| 536 | entry->di_type = var_peer->di_type; | 586 | entry->di_type = var_peer->di_type; |
| 537 | entry->data.structure.complete = true; | 587 | entry->data.structure.complete = true; |
| | 588 | entry->data.structure.zero_bits_known = true; |
| 538 | | 589 | |
| 539 | *parent_pointer = entry; | 590 | *parent_pointer = entry; |
| 540 | return entry; | 591 | return entry; |
| ... | @@ -544,7 +595,7 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c | ... | @@ -544,7 +595,7 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c |
| 544 | // If the child type is []const T then we need to make sure the type ref | 595 | // If the child type is []const T then we need to make sure the type ref |
| 545 | // and debug info is the same as if the child type were []T. | 596 | // and debug info is the same as if the child type were []T. |
| 546 | if (is_slice(child_type)) { | 597 | if (is_slice(child_type)) { |
| 547 | TypeTableEntry *ptr_type = child_type->data.structure.fields[0].type_entry; | 598 | TypeTableEntry *ptr_type = child_type->data.structure.fields[slice_ptr_index].type_entry; |
| 548 | assert(ptr_type->id == TypeTableEntryIdPointer); | 599 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 549 | if (ptr_type->data.pointer.is_const) { | 600 | if (ptr_type->data.pointer.is_const) { |
| 550 | TypeTableEntry *non_const_child_type = get_slice_type(g, | 601 | TypeTableEntry *non_const_child_type = get_slice_type(g, |
| ... | @@ -560,11 +611,6 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c | ... | @@ -560,11 +611,6 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c |
| 560 | buf_appendf(&entry->name, "[]%s", buf_ptr(&child_type->name)); | 611 | buf_appendf(&entry->name, "[]%s", buf_ptr(&child_type->name)); |
| 561 | | 612 | |
| 562 | slice_type_common_init(g, child_type, is_const, entry); | 613 | slice_type_common_init(g, child_type, is_const, entry); |
| 563 | if (child_type->zero_bits) { | | |
| 564 | entry->data.structure.gen_field_count = 1; | | |
| 565 | entry->data.structure.fields[0].gen_index = SIZE_MAX; | | |
| 566 | entry->data.structure.fields[1].gen_index = 0; | | |
| 567 | } | | |
| 568 | | 614 | |
| 569 | if (!entry->type_ref) { | 615 | if (!entry->type_ref) { |
| 570 | entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&entry->name)); | 616 | entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&entry->name)); |
| ... | @@ -582,12 +628,6 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c | ... | @@ -582,12 +628,6 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c |
| 582 | }; | 628 | }; |
| 583 | LLVMStructSetBody(entry->type_ref, element_types, 1, false); | 629 | LLVMStructSetBody(entry->type_ref, element_types, 1, false); |
| 584 | | 630 | |
| 585 | slice_type_common_init(g, child_type, is_const, entry); | | |
| 586 | | | |
| 587 | entry->data.structure.gen_field_count = 1; | | |
| 588 | entry->data.structure.fields[0].gen_index = -1; | | |
| 589 | entry->data.structure.fields[1].gen_index = 0; | | |
| 590 | | | |
| 591 | TypeTableEntry *usize_type = g->builtin_types.entry_usize; | 631 | TypeTableEntry *usize_type = g->builtin_types.entry_usize; |
| 592 | uint64_t len_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, usize_type->type_ref); | 632 | uint64_t len_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, usize_type->type_ref); |
| 593 | uint64_t len_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, usize_type->type_ref); | 633 | uint64_t len_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, usize_type->type_ref); |
| ... | @@ -622,8 +662,6 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c | ... | @@ -622,8 +662,6 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c |
| 622 | }; | 662 | }; |
| 623 | LLVMStructSetBody(entry->type_ref, element_types, element_count, false); | 663 | LLVMStructSetBody(entry->type_ref, element_types, element_count, false); |
| 624 | | 664 | |
| 625 | slice_type_common_init(g, child_type, is_const, entry); | | |
| 626 | | | |
| 627 | | 665 | |
| 628 | uint64_t ptr_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, pointer_type->type_ref); | 666 | uint64_t ptr_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, pointer_type->type_ref); |
| 629 | uint64_t ptr_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, pointer_type->type_ref); | 667 | uint64_t ptr_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, pointer_type->type_ref); |
| ... | @@ -664,6 +702,7 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c | ... | @@ -664,6 +702,7 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c |
| 664 | | 702 | |
| 665 | | 703 | |
| 666 | entry->data.structure.complete = true; | 704 | entry->data.structure.complete = true; |
| | 705 | entry->data.structure.zero_bits_known = true; |
| 667 | | 706 | |
| 668 | *parent_pointer = entry; | 707 | *parent_pointer = entry; |
| 669 | return entry; | 708 | return entry; |
| ... | @@ -706,6 +745,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { | ... | @@ -706,6 +745,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { |
| 706 | if (table_entry) { | 745 | if (table_entry) { |
| 707 | return table_entry->value; | 746 | return table_entry->value; |
| 708 | } | 747 | } |
| | 748 | ensure_complete_type(g, fn_type_id->return_type); |
| 709 | | 749 | |
| 710 | TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn); | 750 | TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn); |
| 711 | fn_type->data.fn.fn_type_id = *fn_type_id; | 751 | fn_type->data.fn.fn_type_id = *fn_type_id; |
| ... | @@ -750,7 +790,6 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { | ... | @@ -750,7 +790,6 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { |
| 750 | // next, loop over the parameters again and compute debug information | 790 | // next, loop over the parameters again and compute debug information |
| 751 | // and codegen information | 791 | // and codegen information |
| 752 | if (!skip_debug_info) { | 792 | if (!skip_debug_info) { |
| 753 | ensure_complete_type(g, fn_type_id->return_type); | | |
| 754 | bool first_arg_return = !fn_type_id->is_extern && handle_is_ptr(fn_type_id->return_type); | 793 | bool first_arg_return = !fn_type_id->is_extern && handle_is_ptr(fn_type_id->return_type); |
| 755 | // +1 for maybe making the first argument the return value | 794 | // +1 for maybe making the first argument the return value |
| 756 | LLVMTypeRef *gen_param_types = allocate<LLVMTypeRef>(1 + fn_type_id->param_count); | 795 | LLVMTypeRef *gen_param_types = allocate<LLVMTypeRef>(1 + fn_type_id->param_count); |
| ... | @@ -1056,33 +1095,31 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1056,33 +1095,31 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1056 | // if you change this logic you likely must also change similar logic in parseh.cpp | 1095 | // if you change this logic you likely must also change similar logic in parseh.cpp |
| 1057 | assert(enum_type->id == TypeTableEntryIdEnum); | 1096 | assert(enum_type->id == TypeTableEntryIdEnum); |
| 1058 | | 1097 | |
| | 1098 | resolve_enum_zero_bits(g, enum_type); |
| | 1099 | if (enum_type->data.enumeration.is_invalid) |
| | 1100 | return; |
| | 1101 | |
| 1059 | AstNode *decl_node = enum_type->data.enumeration.decl_node; | 1102 | AstNode *decl_node = enum_type->data.enumeration.decl_node; |
| 1060 | | 1103 | |
| 1061 | if (enum_type->data.enumeration.embedded_in_current) { | 1104 | if (enum_type->data.enumeration.embedded_in_current) { |
| 1062 | if (!enum_type->data.enumeration.reported_infinite_err) { | 1105 | if (!enum_type->data.enumeration.reported_infinite_err) { |
| 1063 | enum_type->data.enumeration.reported_infinite_err = true; | 1106 | enum_type->data.enumeration.reported_infinite_err = true; |
| 1064 | add_node_error(g, decl_node, buf_sprintf("enum has infinite size")); | 1107 | add_node_error(g, decl_node, buf_sprintf("enum contains itself")); |
| 1065 | } | 1108 | } |
| 1066 | return; | 1109 | return; |
| 1067 | } | 1110 | } |
| 1068 | | 1111 | |
| 1069 | if (enum_type->data.enumeration.fields) { | 1112 | assert(!enum_type->data.enumeration.zero_bits_loop_flag); |
| 1070 | // we already resolved this type. skip | | |
| 1071 | return; | | |
| 1072 | } | | |
| 1073 | | | |
| 1074 | assert(decl_node->type == NodeTypeContainerDecl); | 1113 | assert(decl_node->type == NodeTypeContainerDecl); |
| 1075 | assert(enum_type->di_type); | 1114 | assert(enum_type->di_type); |
| 1076 | | 1115 | |
| 1077 | uint32_t field_count = decl_node->data.container_decl.fields.length; | 1116 | uint32_t field_count = enum_type->data.enumeration.src_field_count; |
| 1078 | | 1117 | |
| 1079 | enum_type->data.enumeration.src_field_count = field_count; | 1118 | assert(enum_type->data.enumeration.fields); |
| 1080 | enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); | | |
| 1081 | ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count); | 1119 | ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count); |
| 1082 | | 1120 | |
| 1083 | // we possibly allocate too much here since gen_field_count can be lower than field_count. | 1121 | uint32_t gen_field_count = enum_type->data.enumeration.gen_field_count; |
| 1084 | // the only problem is potential wasted space though. | 1122 | ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(gen_field_count); |
| 1085 | ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(field_count); | | |
| 1086 | | 1123 | |
| 1087 | TypeTableEntry *biggest_union_member = nullptr; | 1124 | TypeTableEntry *biggest_union_member = nullptr; |
| 1088 | uint64_t biggest_align_in_bits = 0; | 1125 | uint64_t biggest_align_in_bits = 0; |
| ... | @@ -1094,14 +1131,10 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1094,14 +1131,10 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1094 | // set temporary flag | 1131 | // set temporary flag |
| 1095 | enum_type->data.enumeration.embedded_in_current = true; | 1132 | enum_type->data.enumeration.embedded_in_current = true; |
| 1096 | | 1133 | |
| 1097 | size_t gen_field_index = 0; | | |
| 1098 | for (uint32_t i = 0; i < field_count; i += 1) { | 1134 | for (uint32_t i = 0; i < field_count; i += 1) { |
| 1099 | AstNode *field_node = decl_node->data.container_decl.fields.at(i); | 1135 | AstNode *field_node = decl_node->data.container_decl.fields.at(i); |
| 1100 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; | 1136 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; |
| 1101 | type_enum_field->name = field_node->data.struct_field.name; | 1137 | TypeTableEntry *field_type = type_enum_field->type_entry; |
| 1102 | TypeTableEntry *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type); | | |
| 1103 | type_enum_field->type_entry = field_type; | | |
| 1104 | type_enum_field->value = i; | | |
| 1105 | | 1138 | |
| 1106 | di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i); | 1139 | di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i); |
| 1107 | | 1140 | |
| ... | @@ -1120,7 +1153,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1120,7 +1153,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1120 | assert(debug_size_in_bits > 0); | 1153 | assert(debug_size_in_bits > 0); |
| 1121 | assert(debug_align_in_bits > 0); | 1154 | assert(debug_align_in_bits > 0); |
| 1122 | | 1155 | |
| 1123 | union_inner_di_types[gen_field_index] = ZigLLVMCreateDebugMemberType(g->dbuilder, | 1156 | union_inner_di_types[type_enum_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder, |
| 1124 | ZigLLVMTypeToScope(enum_type->di_type), buf_ptr(type_enum_field->name), | 1157 | ZigLLVMTypeToScope(enum_type->di_type), buf_ptr(type_enum_field->name), |
| 1125 | import->di_file, field_node->line + 1, | 1158 | import->di_file, field_node->line + 1, |
| 1126 | debug_size_in_bits, | 1159 | debug_size_in_bits, |
| ... | @@ -1136,8 +1169,6 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1136,8 +1169,6 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1136 | biggest_union_member = field_type; | 1169 | biggest_union_member = field_type; |
| 1137 | biggest_union_member_size_in_bits = debug_size_in_bits; | 1170 | biggest_union_member_size_in_bits = debug_size_in_bits; |
| 1138 | } | 1171 | } |
| 1139 | | | |
| 1140 | gen_field_index += 1; | | |
| 1141 | } | 1172 | } |
| 1142 | | 1173 | |
| 1143 | // unset temporary flag | 1174 | // unset temporary flag |
| ... | @@ -1145,7 +1176,6 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1145,7 +1176,6 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1145 | enum_type->data.enumeration.complete = true; | 1176 | enum_type->data.enumeration.complete = true; |
| 1146 | | 1177 | |
| 1147 | if (!enum_type->data.enumeration.is_invalid) { | 1178 | if (!enum_type->data.enumeration.is_invalid) { |
| 1148 | enum_type->data.enumeration.gen_field_count = gen_field_index; | | |
| 1149 | enum_type->data.enumeration.union_type = biggest_union_member; | 1179 | enum_type->data.enumeration.union_type = biggest_union_member; |
| 1150 | | 1180 | |
| 1151 | TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count); | 1181 | TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count); |
| ... | @@ -1176,7 +1206,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1176,7 +1206,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1176 | ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder, | 1206 | ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder, |
| 1177 | ZigLLVMTypeToScope(enum_type->di_type), "AnonUnion", import->di_file, decl_node->line + 1, | 1207 | ZigLLVMTypeToScope(enum_type->di_type), "AnonUnion", import->di_file, decl_node->line + 1, |
| 1178 | biggest_union_member_size_in_bits, biggest_align_in_bits, 0, union_inner_di_types, | 1208 | biggest_union_member_size_in_bits, biggest_align_in_bits, 0, union_inner_di_types, |
| 1179 | gen_field_index, 0, ""); | 1209 | gen_field_count, 0, ""); |
| 1180 | | 1210 | |
| 1181 | // create debug types for members of root struct | 1211 | // create debug types for members of root struct |
| 1182 | uint64_t tag_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, enum_type->type_ref, 0); | 1212 | uint64_t tag_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, enum_type->type_ref, 0); |
| ... | @@ -1233,9 +1263,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { | ... | @@ -1233,9 +1263,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1233 | | 1263 | |
| 1234 | ZigLLVMReplaceTemporary(g->dbuilder, enum_type->di_type, tag_di_type); | 1264 | ZigLLVMReplaceTemporary(g->dbuilder, enum_type->di_type, tag_di_type); |
| 1235 | enum_type->di_type = tag_di_type; | 1265 | enum_type->di_type = tag_di_type; |
| 1236 | | | |
| 1237 | } | 1266 | } |
| 1238 | | | |
| 1239 | } | 1267 | } |
| 1240 | } | 1268 | } |
| 1241 | | 1269 | |
| ... | @@ -1244,51 +1272,38 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { | ... | @@ -1244,51 +1272,38 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { |
| 1244 | // parseh.cpp | 1272 | // parseh.cpp |
| 1245 | assert(struct_type->id == TypeTableEntryIdStruct); | 1273 | assert(struct_type->id == TypeTableEntryIdStruct); |
| 1246 | | 1274 | |
| | 1275 | resolve_struct_zero_bits(g, struct_type); |
| | 1276 | if (struct_type->data.structure.is_invalid) |
| | 1277 | return; |
| | 1278 | |
| 1247 | AstNode *decl_node = struct_type->data.structure.decl_node; | 1279 | AstNode *decl_node = struct_type->data.structure.decl_node; |
| 1248 | | 1280 | |
| 1249 | if (struct_type->data.structure.embedded_in_current) { | 1281 | if (struct_type->data.structure.embedded_in_current) { |
| 1250 | struct_type->data.structure.is_invalid = true; | 1282 | struct_type->data.structure.is_invalid = true; |
| 1251 | if (!struct_type->data.structure.reported_infinite_err) { | 1283 | if (!struct_type->data.structure.reported_infinite_err) { |
| 1252 | struct_type->data.structure.reported_infinite_err = true; | 1284 | struct_type->data.structure.reported_infinite_err = true; |
| 1253 | add_node_error(g, decl_node, | 1285 | add_node_error(g, decl_node, buf_sprintf("struct contains itself")); |
| 1254 | buf_sprintf("struct has infinite size")); | | |
| 1255 | } | 1286 | } |
| 1256 | return; | 1287 | return; |
| 1257 | } | 1288 | } |
| 1258 | | 1289 | |
| 1259 | if (struct_type->data.structure.fields) { | 1290 | assert(!struct_type->data.structure.zero_bits_loop_flag); |
| 1260 | // we already resolved this type. skip | 1291 | assert(struct_type->data.enumeration.fields); |
| 1261 | return; | | |
| 1262 | } | | |
| 1263 | | | |
| 1264 | assert(decl_node->type == NodeTypeContainerDecl); | 1292 | assert(decl_node->type == NodeTypeContainerDecl); |
| 1265 | assert(struct_type->di_type); | | |
| 1266 | | | |
| 1267 | size_t field_count = decl_node->data.container_decl.fields.length; | | |
| 1268 | | 1293 | |
| 1269 | struct_type->data.structure.src_field_count = field_count; | 1294 | size_t field_count = struct_type->data.structure.src_field_count; |
| 1270 | struct_type->data.structure.fields = allocate<TypeStructField>(field_count); | | |
| 1271 | | 1295 | |
| 1272 | // we possibly allocate too much here since gen_field_count can be lower than field_count. | 1296 | size_t gen_field_count = struct_type->data.structure.gen_field_count; |
| 1273 | // the only problem is potential wasted space though. | 1297 | LLVMTypeRef *element_types = allocate<LLVMTypeRef>(gen_field_count); |
| 1274 | LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count); | | |
| 1275 | | 1298 | |
| 1276 | // this field should be set to true only during the recursive calls to resolve_struct_type | 1299 | // this field should be set to true only during the recursive calls to resolve_struct_type |
| 1277 | struct_type->data.structure.embedded_in_current = true; | 1300 | struct_type->data.structure.embedded_in_current = true; |
| 1278 | | 1301 | |
| 1279 | Scope *scope = &struct_type->data.structure.decls_scope->base; | 1302 | Scope *scope = &struct_type->data.structure.decls_scope->base; |
| 1280 | ImportTableEntry *import = get_scope_import(scope); | | |
| 1281 | | 1303 | |
| 1282 | size_t gen_field_index = 0; | | |
| 1283 | for (size_t i = 0; i < field_count; i += 1) { | 1304 | for (size_t i = 0; i < field_count; i += 1) { |
| 1284 | AstNode *field_node = decl_node->data.container_decl.fields.at(i); | | |
| 1285 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; | 1305 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; |
| 1286 | type_struct_field->name = field_node->data.struct_field.name; | 1306 | TypeTableEntry *field_type = type_struct_field->type_entry; |
| 1287 | TypeTableEntry *field_type = analyze_type_expr(g, scope, | | |
| 1288 | field_node->data.struct_field.type); | | |
| 1289 | type_struct_field->type_entry = field_type; | | |
| 1290 | type_struct_field->src_index = i; | | |
| 1291 | type_struct_field->gen_index = SIZE_MAX; | | |
| 1292 | | 1307 | |
| 1293 | ensure_complete_type(g, field_type); | 1308 | ensure_complete_type(g, field_type); |
| 1294 | if (field_type->id == TypeTableEntryIdInvalid) { | 1309 | if (field_type->id == TypeTableEntryIdInvalid) { |
| ... | @@ -1299,31 +1314,31 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { | ... | @@ -1299,31 +1314,31 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { |
| 1299 | if (!type_has_bits(field_type)) | 1314 | if (!type_has_bits(field_type)) |
| 1300 | continue; | 1315 | continue; |
| 1301 | | 1316 | |
| 1302 | type_struct_field->gen_index = gen_field_index; | 1317 | element_types[type_struct_field->gen_index] = field_type->type_ref; |
| 1303 | | 1318 | assert(element_types[type_struct_field->gen_index]); |
| 1304 | element_types[gen_field_index] = field_type->type_ref; | | |
| 1305 | assert(element_types[gen_field_index]); | | |
| 1306 | | | |
| 1307 | gen_field_index += 1; | | |
| 1308 | } | 1319 | } |
| 1309 | struct_type->data.structure.embedded_in_current = false; | 1320 | struct_type->data.structure.embedded_in_current = false; |
| 1310 | | | |
| 1311 | struct_type->data.structure.gen_field_count = gen_field_index; | | |
| 1312 | struct_type->data.structure.complete = true; | 1321 | struct_type->data.structure.complete = true; |
| 1313 | | 1322 | |
| 1314 | if (struct_type->data.structure.is_invalid) { | 1323 | if (struct_type->data.structure.is_invalid) |
| | 1324 | return; |
| | 1325 | |
| | 1326 | if (struct_type->zero_bits) { |
| | 1327 | struct_type->type_ref = LLVMVoidType(); |
| | 1328 | struct_type->di_type = g->builtin_types.entry_void->di_type; |
| 1315 | return; | 1329 | return; |
| 1316 | } | 1330 | } |
| | 1331 | assert(struct_type->di_type); |
| 1317 | | 1332 | |
| 1318 | size_t gen_field_count = gen_field_index; | | |
| 1319 | LLVMStructSetBody(struct_type->type_ref, element_types, gen_field_count, false); | 1333 | LLVMStructSetBody(struct_type->type_ref, element_types, gen_field_count, false); |
| 1320 | | 1334 | |
| 1321 | ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(gen_field_count); | 1335 | ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(gen_field_count); |
| 1322 | | 1336 | |
| | 1337 | ImportTableEntry *import = get_scope_import(scope); |
| 1323 | for (size_t i = 0; i < field_count; i += 1) { | 1338 | for (size_t i = 0; i < field_count; i += 1) { |
| 1324 | AstNode *field_node = decl_node->data.container_decl.fields.at(i); | 1339 | AstNode *field_node = decl_node->data.container_decl.fields.at(i); |
| 1325 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; | 1340 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; |
| 1326 | gen_field_index = type_struct_field->gen_index; | 1341 | size_t gen_field_index = type_struct_field->gen_index; |
| 1327 | if (gen_field_index == SIZE_MAX) { | 1342 | if (gen_field_index == SIZE_MAX) { |
| 1328 | continue; | 1343 | continue; |
| 1329 | } | 1344 | } |
| ... | @@ -1362,13 +1377,122 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { | ... | @@ -1362,13 +1377,122 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { |
| 1362 | ZigLLVMReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type); | 1377 | ZigLLVMReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type); |
| 1363 | struct_type->di_type = replacement_di_type; | 1378 | struct_type->di_type = replacement_di_type; |
| 1364 | | 1379 | |
| 1365 | struct_type->zero_bits = (debug_size_in_bits == 0); | 1380 | assert((debug_size_in_bits == 0) == struct_type->zero_bits); |
| 1366 | } | 1381 | } |
| 1367 | | 1382 | |
| 1368 | static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) { | 1383 | static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) { |
| 1369 | zig_panic("TODO"); | 1384 | zig_panic("TODO"); |
| 1370 | } | 1385 | } |
| 1371 | | 1386 | |
| | 1387 | static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type) { |
| | 1388 | assert(enum_type->id == TypeTableEntryIdEnum); |
| | 1389 | |
| | 1390 | if (enum_type->data.enumeration.zero_bits_known) |
| | 1391 | return; |
| | 1392 | |
| | 1393 | if (enum_type->data.enumeration.zero_bits_loop_flag) { |
| | 1394 | enum_type->data.enumeration.zero_bits_known = true; |
| | 1395 | return; |
| | 1396 | } |
| | 1397 | |
| | 1398 | enum_type->data.enumeration.zero_bits_loop_flag = true; |
| | 1399 | |
| | 1400 | AstNode *decl_node = enum_type->data.enumeration.decl_node; |
| | 1401 | assert(decl_node->type == NodeTypeContainerDecl); |
| | 1402 | assert(enum_type->di_type); |
| | 1403 | |
| | 1404 | assert(!enum_type->data.enumeration.fields); |
| | 1405 | uint32_t field_count = decl_node->data.container_decl.fields.length; |
| | 1406 | enum_type->data.enumeration.src_field_count = field_count; |
| | 1407 | enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); |
| | 1408 | |
| | 1409 | Scope *scope = &enum_type->data.enumeration.decls_scope->base; |
| | 1410 | |
| | 1411 | uint32_t gen_field_index = 0; |
| | 1412 | for (uint32_t i = 0; i < field_count; i += 1) { |
| | 1413 | AstNode *field_node = decl_node->data.container_decl.fields.at(i); |
| | 1414 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; |
| | 1415 | type_enum_field->name = field_node->data.struct_field.name; |
| | 1416 | TypeTableEntry *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type); |
| | 1417 | type_enum_field->type_entry = field_type; |
| | 1418 | type_enum_field->value = i; |
| | 1419 | |
| | 1420 | type_ensure_zero_bits_known(g, field_type); |
| | 1421 | if (field_type->id == TypeTableEntryIdInvalid) { |
| | 1422 | enum_type->data.enumeration.is_invalid = true; |
| | 1423 | continue; |
| | 1424 | } |
| | 1425 | |
| | 1426 | if (!type_has_bits(field_type)) |
| | 1427 | continue; |
| | 1428 | |
| | 1429 | type_enum_field->gen_index = gen_field_index; |
| | 1430 | gen_field_index += 1; |
| | 1431 | } |
| | 1432 | |
| | 1433 | enum_type->data.enumeration.zero_bits_loop_flag = false; |
| | 1434 | enum_type->data.enumeration.gen_field_count = gen_field_index; |
| | 1435 | enum_type->zero_bits = (gen_field_index == 0 && field_count < 2); |
| | 1436 | enum_type->data.enumeration.zero_bits_known = true; |
| | 1437 | } |
| | 1438 | |
| | 1439 | static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type) { |
| | 1440 | assert(struct_type->id == TypeTableEntryIdStruct); |
| | 1441 | |
| | 1442 | if (struct_type->data.structure.zero_bits_known) |
| | 1443 | return; |
| | 1444 | |
| | 1445 | if (struct_type->data.structure.zero_bits_loop_flag) { |
| | 1446 | struct_type->data.structure.zero_bits_known = true; |
| | 1447 | return; |
| | 1448 | } |
| | 1449 | |
| | 1450 | struct_type->data.structure.zero_bits_loop_flag = true; |
| | 1451 | |
| | 1452 | AstNode *decl_node = struct_type->data.structure.decl_node; |
| | 1453 | assert(decl_node->type == NodeTypeContainerDecl); |
| | 1454 | assert(struct_type->di_type); |
| | 1455 | |
| | 1456 | assert(!struct_type->data.structure.fields); |
| | 1457 | size_t field_count = decl_node->data.container_decl.fields.length; |
| | 1458 | struct_type->data.structure.src_field_count = field_count; |
| | 1459 | struct_type->data.structure.fields = allocate<TypeStructField>(field_count); |
| | 1460 | |
| | 1461 | Scope *scope = &struct_type->data.structure.decls_scope->base; |
| | 1462 | |
| | 1463 | size_t gen_field_index = 0; |
| | 1464 | for (size_t i = 0; i < field_count; i += 1) { |
| | 1465 | AstNode *field_node = decl_node->data.container_decl.fields.at(i); |
| | 1466 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; |
| | 1467 | type_struct_field->name = field_node->data.struct_field.name; |
| | 1468 | TypeTableEntry *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type); |
| | 1469 | type_struct_field->type_entry = field_type; |
| | 1470 | type_struct_field->src_index = i; |
| | 1471 | type_struct_field->gen_index = SIZE_MAX; |
| | 1472 | |
| | 1473 | type_ensure_zero_bits_known(g, field_type); |
| | 1474 | if (field_type->id == TypeTableEntryIdInvalid) { |
| | 1475 | struct_type->data.structure.is_invalid = true; |
| | 1476 | continue; |
| | 1477 | } |
| | 1478 | |
| | 1479 | if (!type_has_bits(field_type)) |
| | 1480 | continue; |
| | 1481 | |
| | 1482 | type_struct_field->gen_index = gen_field_index; |
| | 1483 | gen_field_index += 1; |
| | 1484 | } |
| | 1485 | |
| | 1486 | struct_type->data.structure.zero_bits_loop_flag = false; |
| | 1487 | struct_type->data.structure.gen_field_count = gen_field_index; |
| | 1488 | struct_type->zero_bits = (gen_field_index == 0); |
| | 1489 | struct_type->data.structure.zero_bits_known = true; |
| | 1490 | } |
| | 1491 | |
| | 1492 | static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) { |
| | 1493 | zig_panic("TODO resolve_union_zero_bits"); |
| | 1494 | } |
| | 1495 | |
| 1372 | static void get_fully_qualified_decl_name_internal(Buf *buf, Scope *scope, uint8_t sep) { | 1496 | static void get_fully_qualified_decl_name_internal(Buf *buf, Scope *scope, uint8_t sep) { |
| 1373 | if (!scope) | 1497 | if (!scope) |
| 1374 | return; | 1498 | return; |
| ... | @@ -3064,6 +3188,16 @@ void ensure_complete_type(CodeGen *g, TypeTableEntry *type_entry) { | ... | @@ -3064,6 +3188,16 @@ void ensure_complete_type(CodeGen *g, TypeTableEntry *type_entry) { |
| 3064 | } | 3188 | } |
| 3065 | } | 3189 | } |
| 3066 | | 3190 | |
| | 3191 | void type_ensure_zero_bits_known(CodeGen *g, TypeTableEntry *type_entry) { |
| | 3192 | if (type_entry->id == TypeTableEntryIdStruct) { |
| | 3193 | resolve_struct_zero_bits(g, type_entry); |
| | 3194 | } else if (type_entry->id == TypeTableEntryIdEnum) { |
| | 3195 | resolve_enum_zero_bits(g, type_entry); |
| | 3196 | } else if (type_entry->id == TypeTableEntryIdUnion) { |
| | 3197 | resolve_union_zero_bits(g, type_entry); |
| | 3198 | } |
| | 3199 | } |
| | 3200 | |
| 3067 | bool ir_get_var_is_comptime(VariableTableEntry *var) { | 3201 | bool ir_get_var_is_comptime(VariableTableEntry *var) { |
| 3068 | if (!var->is_comptime) | 3202 | if (!var->is_comptime) |
| 3069 | return false; | 3203 | return false; |