| ... | ... | @@ -20,6 +20,10 @@ static const size_t default_backward_branch_quota = 1000; |
| 20 | 20 | static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type); |
| 21 | 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 | 27 | AstNode *first_executing_node(AstNode *node) { |
| 24 | 28 | switch (node->type) { |
| 25 | 29 | case NodeTypeFnCallExpr: |
| ... | ... | @@ -257,6 +261,44 @@ bool type_is_complete(TypeTableEntry *type_entry) { |
| 257 | 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 | 302 | uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry) { |
| 261 | 303 | if (type_has_bits(type_entry)) { |
| 262 | 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 | 517 | return entry; |
| 476 | 518 | } else { |
| 477 | 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 | 520 | entry->zero_bits = (array_size == 0) || child_type->zero_bits; |
| 480 | 521 | |
| 481 | 522 | buf_resize(&entry->name, 0); |
| 482 | 523 | buf_appendf(&entry->name, "[%" PRIu64 "]%s", array_size, buf_ptr(&child_type->name)); |
| 483 | 524 | |
| 484 | 525 | if (!entry->zero_bits) { |
| 526 | entry->type_ref = child_type->type_ref ? LLVMArrayType(child_type->type_ref, array_size) : nullptr; |
| 527 | |
| 485 | 528 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); |
| 486 | 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 | 550 | entry->data.structure.src_field_count = element_count; |
| 508 | 551 | entry->data.structure.gen_field_count = element_count; |
| 509 | 552 | entry->data.structure.fields = allocate<TypeStructField>(element_count); |
| 510 | | entry->data.structure.fields[0].name = buf_create_from_str("ptr"); |
| 511 | | entry->data.structure.fields[0].type_entry = pointer_type; |
| 512 | | entry->data.structure.fields[0].src_index = 0; |
| 513 | | entry->data.structure.fields[0].gen_index = 0; |
| 514 | | entry->data.structure.fields[1].name = buf_create_from_str("len"); |
| 515 | | entry->data.structure.fields[1].type_entry = g->builtin_types.entry_usize; |
| 516 | | entry->data.structure.fields[1].src_index = 1; |
| 517 | | entry->data.structure.fields[1].gen_index = 1; |
| 553 | entry->data.structure.fields[slice_ptr_index].name = buf_create_from_str("ptr"); |
| 554 | entry->data.structure.fields[slice_ptr_index].type_entry = pointer_type; |
| 555 | entry->data.structure.fields[slice_ptr_index].src_index = slice_ptr_index; |
| 556 | entry->data.structure.fields[slice_ptr_index].gen_index = 0; |
| 557 | entry->data.structure.fields[slice_len_index].name = buf_create_from_str("len"); |
| 558 | entry->data.structure.fields[slice_len_index].type_entry = g->builtin_types.entry_usize; |
| 559 | entry->data.structure.fields[slice_len_index].src_index = slice_len_index; |
| 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 | 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 | 585 | entry->type_ref = var_peer->type_ref; |
| 536 | 586 | entry->di_type = var_peer->di_type; |
| 537 | 587 | entry->data.structure.complete = true; |
| 588 | entry->data.structure.zero_bits_known = true; |
| 538 | 589 | |
| 539 | 590 | *parent_pointer = entry; |
| 540 | 591 | return entry; |
| ... | ... | @@ -544,7 +595,7 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c |
| 544 | 595 | // If the child type is []const T then we need to make sure the type ref |
| 545 | 596 | // and debug info is the same as if the child type were []T. |
| 546 | 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 | 599 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 549 | 600 | if (ptr_type->data.pointer.is_const) { |
| 550 | 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 | 611 | buf_appendf(&entry->name, "[]%s", buf_ptr(&child_type->name)); |
| 561 | 612 | |
| 562 | 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 | 615 | if (!entry->type_ref) { |
| 570 | 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 | 628 | }; |
| 583 | 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 | 631 | TypeTableEntry *usize_type = g->builtin_types.entry_usize; |
| 592 | 632 | uint64_t len_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, usize_type->type_ref); |
| 593 | 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 | 662 | }; |
| 623 | 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 | 666 | uint64_t ptr_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, pointer_type->type_ref); |
| 629 | 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 | 702 | |
| 665 | 703 | |
| 666 | 704 | entry->data.structure.complete = true; |
| 705 | entry->data.structure.zero_bits_known = true; |
| 667 | 706 | |
| 668 | 707 | *parent_pointer = entry; |
| 669 | 708 | return entry; |
| ... | ... | @@ -706,6 +745,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { |
| 706 | 745 | if (table_entry) { |
| 707 | 746 | return table_entry->value; |
| 708 | 747 | } |
| 748 | ensure_complete_type(g, fn_type_id->return_type); |
| 709 | 749 | |
| 710 | 750 | TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn); |
| 711 | 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 | 790 | // next, loop over the parameters again and compute debug information |
| 751 | 791 | // and codegen information |
| 752 | 792 | if (!skip_debug_info) { |
| 753 | | ensure_complete_type(g, fn_type_id->return_type); |
| 754 | 793 | bool first_arg_return = !fn_type_id->is_extern && handle_is_ptr(fn_type_id->return_type); |
| 755 | 794 | // +1 for maybe making the first argument the return value |
| 756 | 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 | 1095 | // if you change this logic you likely must also change similar logic in parseh.cpp |
| 1057 | 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 | 1102 | AstNode *decl_node = enum_type->data.enumeration.decl_node; |
| 1060 | 1103 | |
| 1061 | 1104 | if (enum_type->data.enumeration.embedded_in_current) { |
| 1062 | 1105 | if (!enum_type->data.enumeration.reported_infinite_err) { |
| 1063 | 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 | 1109 | return; |
| 1067 | 1110 | } |
| 1068 | 1111 | |
| 1069 | | if (enum_type->data.enumeration.fields) { |
| 1070 | | // we already resolved this type. skip |
| 1071 | | return; |
| 1072 | | } |
| 1073 | | |
| 1112 | assert(!enum_type->data.enumeration.zero_bits_loop_flag); |
| 1074 | 1113 | assert(decl_node->type == NodeTypeContainerDecl); |
| 1075 | 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; |
| 1080 | | enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); |
| 1118 | assert(enum_type->data.enumeration.fields); |
| 1081 | 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. |
| 1084 | | // the only problem is potential wasted space though. |
| 1085 | | ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(field_count); |
| 1121 | uint32_t gen_field_count = enum_type->data.enumeration.gen_field_count; |
| 1122 | ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(gen_field_count); |
| 1086 | 1123 | |
| 1087 | 1124 | TypeTableEntry *biggest_union_member = nullptr; |
| 1088 | 1125 | uint64_t biggest_align_in_bits = 0; |
| ... | ... | @@ -1094,14 +1131,10 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1094 | 1131 | // set temporary flag |
| 1095 | 1132 | enum_type->data.enumeration.embedded_in_current = true; |
| 1096 | 1133 | |
| 1097 | | size_t gen_field_index = 0; |
| 1098 | 1134 | for (uint32_t i = 0; i < field_count; i += 1) { |
| 1099 | 1135 | AstNode *field_node = decl_node->data.container_decl.fields.at(i); |
| 1100 | 1136 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; |
| 1101 | | type_enum_field->name = field_node->data.struct_field.name; |
| 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; |
| 1137 | TypeTableEntry *field_type = type_enum_field->type_entry; |
| 1105 | 1138 | |
| 1106 | 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 | 1153 | assert(debug_size_in_bits > 0); |
| 1121 | 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 | 1157 | ZigLLVMTypeToScope(enum_type->di_type), buf_ptr(type_enum_field->name), |
| 1125 | 1158 | import->di_file, field_node->line + 1, |
| 1126 | 1159 | debug_size_in_bits, |
| ... | ... | @@ -1136,8 +1169,6 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1136 | 1169 | biggest_union_member = field_type; |
| 1137 | 1170 | biggest_union_member_size_in_bits = debug_size_in_bits; |
| 1138 | 1171 | } |
| 1139 | | |
| 1140 | | gen_field_index += 1; |
| 1141 | 1172 | } |
| 1142 | 1173 | |
| 1143 | 1174 | // unset temporary flag |
| ... | ... | @@ -1145,7 +1176,6 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { |
| 1145 | 1176 | enum_type->data.enumeration.complete = true; |
| 1146 | 1177 | |
| 1147 | 1178 | if (!enum_type->data.enumeration.is_invalid) { |
| 1148 | | enum_type->data.enumeration.gen_field_count = gen_field_index; |
| 1149 | 1179 | enum_type->data.enumeration.union_type = biggest_union_member; |
| 1150 | 1180 | |
| 1151 | 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 | 1206 | ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder, |
| 1177 | 1207 | ZigLLVMTypeToScope(enum_type->di_type), "AnonUnion", import->di_file, decl_node->line + 1, |
| 1178 | 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 | 1211 | // create debug types for members of root struct |
| 1182 | 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 | 1263 | |
| 1234 | 1264 | ZigLLVMReplaceTemporary(g->dbuilder, enum_type->di_type, tag_di_type); |
| 1235 | 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 | 1272 | // parseh.cpp |
| 1245 | 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 | 1279 | AstNode *decl_node = struct_type->data.structure.decl_node; |
| 1248 | 1280 | |
| 1249 | 1281 | if (struct_type->data.structure.embedded_in_current) { |
| 1250 | 1282 | struct_type->data.structure.is_invalid = true; |
| 1251 | 1283 | if (!struct_type->data.structure.reported_infinite_err) { |
| 1252 | 1284 | struct_type->data.structure.reported_infinite_err = true; |
| 1253 | | add_node_error(g, decl_node, |
| 1254 | | buf_sprintf("struct has infinite size")); |
| 1285 | add_node_error(g, decl_node, buf_sprintf("struct contains itself")); |
| 1255 | 1286 | } |
| 1256 | 1287 | return; |
| 1257 | 1288 | } |
| 1258 | 1289 | |
| 1259 | | if (struct_type->data.structure.fields) { |
| 1260 | | // we already resolved this type. skip |
| 1261 | | return; |
| 1262 | | } |
| 1263 | | |
| 1290 | assert(!struct_type->data.structure.zero_bits_loop_flag); |
| 1291 | assert(struct_type->data.enumeration.fields); |
| 1264 | 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; |
| 1270 | | struct_type->data.structure.fields = allocate<TypeStructField>(field_count); |
| 1294 | size_t field_count = struct_type->data.structure.src_field_count; |
| 1271 | 1295 | |
| 1272 | | // we possibly allocate too much here since gen_field_count can be lower than field_count. |
| 1273 | | // the only problem is potential wasted space though. |
| 1274 | | LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count); |
| 1296 | size_t gen_field_count = struct_type->data.structure.gen_field_count; |
| 1297 | LLVMTypeRef *element_types = allocate<LLVMTypeRef>(gen_field_count); |
| 1275 | 1298 | |
| 1276 | 1299 | // this field should be set to true only during the recursive calls to resolve_struct_type |
| 1277 | 1300 | struct_type->data.structure.embedded_in_current = true; |
| 1278 | 1301 | |
| 1279 | 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 | 1304 | for (size_t i = 0; i < field_count; i += 1) { |
| 1284 | | AstNode *field_node = decl_node->data.container_decl.fields.at(i); |
| 1285 | 1305 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; |
| 1286 | | type_struct_field->name = field_node->data.struct_field.name; |
| 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; |
| 1306 | TypeTableEntry *field_type = type_struct_field->type_entry; |
| 1292 | 1307 | |
| 1293 | 1308 | ensure_complete_type(g, field_type); |
| 1294 | 1309 | if (field_type->id == TypeTableEntryIdInvalid) { |
| ... | ... | @@ -1299,31 +1314,31 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { |
| 1299 | 1314 | if (!type_has_bits(field_type)) |
| 1300 | 1315 | continue; |
| 1301 | 1316 | |
| 1302 | | type_struct_field->gen_index = gen_field_index; |
| 1303 | | |
| 1304 | | element_types[gen_field_index] = field_type->type_ref; |
| 1305 | | assert(element_types[gen_field_index]); |
| 1306 | | |
| 1307 | | gen_field_index += 1; |
| 1317 | element_types[type_struct_field->gen_index] = field_type->type_ref; |
| 1318 | assert(element_types[type_struct_field->gen_index]); |
| 1308 | 1319 | } |
| 1309 | 1320 | struct_type->data.structure.embedded_in_current = false; |
| 1310 | | |
| 1311 | | struct_type->data.structure.gen_field_count = gen_field_index; |
| 1312 | 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 | 1329 | return; |
| 1316 | 1330 | } |
| 1331 | assert(struct_type->di_type); |
| 1317 | 1332 | |
| 1318 | | size_t gen_field_count = gen_field_index; |
| 1319 | 1333 | LLVMStructSetBody(struct_type->type_ref, element_types, gen_field_count, false); |
| 1320 | 1334 | |
| 1321 | 1335 | ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(gen_field_count); |
| 1322 | 1336 | |
| 1337 | ImportTableEntry *import = get_scope_import(scope); |
| 1323 | 1338 | for (size_t i = 0; i < field_count; i += 1) { |
| 1324 | 1339 | AstNode *field_node = decl_node->data.container_decl.fields.at(i); |
| 1325 | 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 | 1342 | if (gen_field_index == SIZE_MAX) { |
| 1328 | 1343 | continue; |
| 1329 | 1344 | } |
| ... | ... | @@ -1362,13 +1377,122 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { |
| 1362 | 1377 | ZigLLVMReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type); |
| 1363 | 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 | 1383 | static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) { |
| 1369 | 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 | 1496 | static void get_fully_qualified_decl_name_internal(Buf *buf, Scope *scope, uint8_t sep) { |
| 1373 | 1497 | if (!scope) |
| 1374 | 1498 | return; |
| ... | ... | @@ -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 | 3201 | bool ir_get_var_is_comptime(VariableTableEntry *var) { |
| 3068 | 3202 | if (!var->is_comptime) |
| 3069 | 3203 | return false; |