| ... | ... | @@ -273,8 +273,12 @@ static TypeTableEntry *get_unknown_size_array_type(CodeGen *g, ImportTableEntry |
| 273 | 273 | entry->data.structure.fields = allocate<TypeStructField>(element_count); |
| 274 | 274 | entry->data.structure.fields[0].name = buf_create_from_str("ptr"); |
| 275 | 275 | entry->data.structure.fields[0].type_entry = pointer_type; |
| 276 | entry->data.structure.fields[0].src_index = 0; |
| 277 | entry->data.structure.fields[0].gen_index = 0; |
| 276 | 278 | entry->data.structure.fields[1].name = buf_create_from_str("len"); |
| 277 | 279 | entry->data.structure.fields[1].type_entry = g->builtin_types.entry_usize; |
| 280 | entry->data.structure.fields[1].src_index = 1; |
| 281 | entry->data.structure.fields[1].gen_index = 1; |
| 278 | 282 | |
| 279 | 283 | LLVMZigDIType *di_element_types[] = { |
| 280 | 284 | pointer_type->di_type, |
| ... | ... | @@ -632,7 +636,7 @@ static void preview_function_labels(CodeGen *g, AstNode *node, FnTableEntry *fn_ |
| 632 | 636 | } |
| 633 | 637 | } |
| 634 | 638 | |
| 635 | | static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type) { |
| 639 | static void resolve_container_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type) { |
| 636 | 640 | assert(struct_type->id == TypeTableEntryIdStruct); |
| 637 | 641 | |
| 638 | 642 | AstNode *decl_node = struct_type->data.structure.decl_node; |
| ... | ... | @@ -655,9 +659,12 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE |
| 655 | 659 | assert(struct_type->di_type); |
| 656 | 660 | |
| 657 | 661 | int field_count = decl_node->data.struct_decl.fields.length; |
| 662 | |
| 658 | 663 | struct_type->data.structure.field_count = field_count; |
| 659 | 664 | struct_type->data.structure.fields = allocate<TypeStructField>(field_count); |
| 660 | 665 | |
| 666 | // we possibly allocate too much here since gen_field_count can be lower than field_count. |
| 667 | // the only problem is potential wasted space though. |
| 661 | 668 | LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count); |
| 662 | 669 | LLVMZigDIType **di_element_types = allocate<LLVMZigDIType*>(field_count); |
| 663 | 670 | |
| ... | ... | @@ -665,33 +672,40 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE |
| 665 | 672 | uint64_t first_field_align_in_bits = 0; |
| 666 | 673 | uint64_t offset_in_bits = 0; |
| 667 | 674 | |
| 668 | | // this field should be set to true only during the recursive calls to resolve_struct_type |
| 675 | // this field should be set to true only during the recursive calls to resolve_container_type |
| 669 | 676 | struct_type->data.structure.embedded_in_current = true; |
| 670 | 677 | |
| 678 | int gen_field_index = 0; |
| 671 | 679 | for (int i = 0; i < field_count; i += 1) { |
| 672 | 680 | AstNode *field_node = decl_node->data.struct_decl.fields.at(i); |
| 673 | 681 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; |
| 674 | 682 | type_struct_field->name = &field_node->data.struct_field.name; |
| 675 | 683 | type_struct_field->type_entry = resolve_type(g, field_node->data.struct_field.type, |
| 676 | 684 | import, import->block_context, false); |
| 685 | type_struct_field->src_index = i; |
| 686 | type_struct_field->gen_index = -1; |
| 677 | 687 | |
| 678 | 688 | if (type_struct_field->type_entry->id == TypeTableEntryIdStruct) { |
| 679 | | resolve_struct_type(g, import, type_struct_field->type_entry); |
| 689 | resolve_container_type(g, import, type_struct_field->type_entry); |
| 680 | 690 | } else if (type_struct_field->type_entry->id == TypeTableEntryIdInvalid) { |
| 681 | 691 | struct_type->data.structure.is_invalid = true; |
| 682 | 692 | continue; |
| 693 | } else if (type_struct_field->type_entry->id == TypeTableEntryIdVoid) { |
| 694 | continue; |
| 683 | 695 | } |
| 684 | 696 | |
| 685 | | di_element_types[i] = LLVMZigCreateDebugMemberType(g->dbuilder, |
| 697 | type_struct_field->gen_index = gen_field_index; |
| 698 | |
| 699 | di_element_types[gen_field_index] = LLVMZigCreateDebugMemberType(g->dbuilder, |
| 686 | 700 | LLVMZigTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name), |
| 687 | 701 | import->di_file, field_node->line + 1, |
| 688 | 702 | type_struct_field->type_entry->size_in_bits, |
| 689 | 703 | type_struct_field->type_entry->align_in_bits, |
| 690 | 704 | offset_in_bits, 0, type_struct_field->type_entry->di_type); |
| 691 | 705 | |
| 692 | | element_types[i] = type_struct_field->type_entry->type_ref; |
| 693 | | assert(di_element_types[i]); |
| 694 | | assert(element_types[i]); |
| 706 | element_types[gen_field_index] = type_struct_field->type_entry->type_ref; |
| 707 | assert(di_element_types[gen_field_index]); |
| 708 | assert(element_types[gen_field_index]); |
| 695 | 709 | |
| 696 | 710 | total_size_in_bits += type_struct_field->type_entry->size_in_bits; |
| 697 | 711 | if (first_field_align_in_bits == 0) { |
| ... | ... | @@ -699,12 +713,13 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE |
| 699 | 713 | } |
| 700 | 714 | offset_in_bits += type_struct_field->type_entry->size_in_bits; |
| 701 | 715 | |
| 716 | gen_field_index += 1; |
| 702 | 717 | } |
| 703 | 718 | struct_type->data.structure.embedded_in_current = false; |
| 704 | 719 | |
| 705 | 720 | if (!struct_type->data.structure.is_invalid) { |
| 706 | 721 | |
| 707 | | LLVMStructSetBody(struct_type->type_ref, element_types, field_count, false); |
| 722 | LLVMStructSetBody(struct_type->type_ref, element_types, gen_field_index, false); |
| 708 | 723 | |
| 709 | 724 | struct_type->align_in_bits = first_field_align_in_bits; |
| 710 | 725 | struct_type->size_in_bits = total_size_in_bits; |
| ... | ... | @@ -713,7 +728,7 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE |
| 713 | 728 | LLVMZigFileToScope(import->di_file), |
| 714 | 729 | buf_ptr(&decl_node->data.struct_decl.name), |
| 715 | 730 | import->di_file, decl_node->line + 1, struct_type->size_in_bits, struct_type->align_in_bits, 0, |
| 716 | | nullptr, di_element_types, field_count, 0, nullptr, ""); |
| 731 | nullptr, di_element_types, gen_field_index, 0, nullptr, ""); |
| 717 | 732 | |
| 718 | 733 | LLVMZigReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type); |
| 719 | 734 | struct_type->di_type = replacement_di_type; |
| ... | ... | @@ -888,7 +903,7 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode |
| 888 | 903 | { |
| 889 | 904 | TypeTableEntry *type_entry = node->data.struct_decl.type_entry; |
| 890 | 905 | |
| 891 | | resolve_struct_type(g, import, type_entry); |
| 906 | resolve_container_type(g, import, type_entry); |
| 892 | 907 | |
| 893 | 908 | // struct member fns will get resolved independently |
| 894 | 909 | break; |
| ... | ... | @@ -1262,17 +1277,14 @@ TypeTableEntry *find_container(BlockContext *context, Buf *name) { |
| 1262 | 1277 | return nullptr; |
| 1263 | 1278 | } |
| 1264 | 1279 | |
| 1265 | | static void get_struct_field(TypeTableEntry *struct_type, Buf *name, TypeStructField **out_tsf, int *out_i) { |
| 1280 | static TypeStructField *get_struct_field(TypeTableEntry *struct_type, Buf *name) { |
| 1266 | 1281 | for (int i = 0; i < struct_type->data.structure.field_count; i += 1) { |
| 1267 | 1282 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; |
| 1268 | 1283 | if (buf_eql_buf(type_struct_field->name, name)) { |
| 1269 | | *out_tsf = type_struct_field; |
| 1270 | | *out_i = i; |
| 1271 | | return; |
| 1284 | return type_struct_field; |
| 1272 | 1285 | } |
| 1273 | 1286 | } |
| 1274 | | *out_tsf = nullptr; |
| 1275 | | *out_i = -1; |
| 1287 | return nullptr; |
| 1276 | 1288 | } |
| 1277 | 1289 | |
| 1278 | 1290 | static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| ... | ... | @@ -1293,9 +1305,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i |
| 1293 | 1305 | TypeTableEntry *bare_struct_type = (struct_type->id == TypeTableEntryIdStruct) ? |
| 1294 | 1306 | struct_type : struct_type->data.pointer.child_type; |
| 1295 | 1307 | |
| 1296 | | get_struct_field(bare_struct_type, field_name, |
| 1297 | | &node->data.field_access_expr.type_struct_field, |
| 1298 | | &node->data.field_access_expr.field_index); |
| 1308 | node->data.field_access_expr.type_struct_field = get_struct_field(bare_struct_type, field_name); |
| 1299 | 1309 | if (node->data.field_access_expr.type_struct_field) { |
| 1300 | 1310 | return_type = node->data.field_access_expr.type_struct_field->type_entry; |
| 1301 | 1311 | } else { |
| ... | ... | @@ -1885,7 +1895,7 @@ static TypeTableEntry *analyze_struct_val_expr(CodeGen *g, ImportTableEntry *imp |
| 1885 | 1895 | continue; |
| 1886 | 1896 | } |
| 1887 | 1897 | |
| 1888 | | val_field_node->data.struct_val_field.index = field_index; |
| 1898 | val_field_node->data.struct_val_field.type_struct_field = type_field; |
| 1889 | 1899 | |
| 1890 | 1900 | analyze_expression(g, import, context, type_field->type_entry, |
| 1891 | 1901 | val_field_node->data.struct_val_field.expr); |