| ... | ... | @@ -18,6 +18,7 @@ static TypeTableEntry *eval_const_expr(CodeGen *g, BlockContext *context, |
| 18 | 18 | static void collect_type_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *type_node, TopLevelDecl *decl_node); |
| 19 | 19 | static VariableTableEntry *analyze_variable_declaration(CodeGen *g, ImportTableEntry *import, |
| 20 | 20 | BlockContext *context, TypeTableEntry *expected_type, AstNode *node); |
| 21 | static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type); |
| 21 | 22 | |
| 22 | 23 | static AstNode *first_executing_node(AstNode *node) { |
| 23 | 24 | switch (node->type) { |
| ... | ... | @@ -116,8 +117,27 @@ TypeTableEntry *new_type_table_entry(TypeTableEntryId id) { |
| 116 | 117 | entry->arrays_by_size.init(2); |
| 117 | 118 | entry->id = id; |
| 118 | 119 | |
| 119 | | if (id == TypeTableEntryIdStruct) { |
| 120 | | entry->data.structure.fn_table.init(8); |
| 120 | switch (id) { |
| 121 | case TypeTableEntryIdInvalid: |
| 122 | case TypeTableEntryIdMetaType: |
| 123 | case TypeTableEntryIdVoid: |
| 124 | case TypeTableEntryIdBool: |
| 125 | case TypeTableEntryIdUnreachable: |
| 126 | case TypeTableEntryIdInt: |
| 127 | case TypeTableEntryIdFloat: |
| 128 | case TypeTableEntryIdPointer: |
| 129 | case TypeTableEntryIdArray: |
| 130 | case TypeTableEntryIdNumberLiteral: |
| 131 | case TypeTableEntryIdMaybe: |
| 132 | // nothing to init |
| 133 | break; |
| 134 | case TypeTableEntryIdStruct: |
| 135 | entry->data.structure.fn_table.init(8); |
| 136 | break; |
| 137 | case TypeTableEntryIdEnum: |
| 138 | entry->data.enumeration.fn_table.init(8); |
| 139 | break; |
| 140 | |
| 121 | 141 | } |
| 122 | 142 | |
| 123 | 143 | return entry; |
| ... | ... | @@ -139,6 +159,35 @@ static TypeTableEntry *get_number_literal_type_unsigned(CodeGen *g, uint64_t x) |
| 139 | 159 | return g->num_lit_types[get_number_literal_kind_unsigned(x)]; |
| 140 | 160 | } |
| 141 | 161 | |
| 162 | static TypeTableEntry *get_int_type_unsigned(CodeGen *g, uint64_t x) { |
| 163 | switch (get_number_literal_kind_unsigned(x)) { |
| 164 | case NumLitU8: |
| 165 | return g->builtin_types.entry_u8; |
| 166 | case NumLitU16: |
| 167 | return g->builtin_types.entry_u16; |
| 168 | case NumLitU32: |
| 169 | return g->builtin_types.entry_u32; |
| 170 | case NumLitU64: |
| 171 | return g->builtin_types.entry_u64; |
| 172 | default: |
| 173 | zig_unreachable(); |
| 174 | } |
| 175 | } |
| 176 | |
| 177 | static TypeTableEntry *get_meta_type(CodeGen *g, TypeTableEntry *child_type) { |
| 178 | if (child_type->meta_parent) { |
| 179 | return child_type->maybe_parent; |
| 180 | } else { |
| 181 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMetaType); |
| 182 | buf_resize(&entry->name, 0); |
| 183 | buf_appendf(&entry->name, "(%s declaration)", buf_ptr(&child_type->name)); |
| 184 | |
| 185 | entry->data.meta_type.child_type = child_type; |
| 186 | child_type->meta_parent = entry; |
| 187 | return entry; |
| 188 | } |
| 189 | } |
| 190 | |
| 142 | 191 | TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const, bool is_noalias) { |
| 143 | 192 | TypeTableEntry **parent_pointer = &child_type->pointer_parent[(is_const ? 1 : 0)][(is_noalias ? 1 : 0)]; |
| 144 | 193 | if (*parent_pointer) { |
| ... | ... | @@ -146,8 +195,12 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool |
| 146 | 195 | } else { |
| 147 | 196 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPointer); |
| 148 | 197 | entry->type_ref = LLVMPointerType(child_type->type_ref, 0); |
| 198 | |
| 199 | const char *const_str = is_const ? "const " : ""; |
| 200 | const char *noalias_str = is_noalias ? "noalias " : ""; |
| 149 | 201 | buf_resize(&entry->name, 0); |
| 150 | | buf_appendf(&entry->name, "&%s%s", is_const ? "const " : "", buf_ptr(&child_type->name)); |
| 202 | buf_appendf(&entry->name, "&%s%s%s", const_str, noalias_str, buf_ptr(&child_type->name)); |
| 203 | |
| 151 | 204 | entry->size_in_bits = g->pointer_size_bytes * 8; |
| 152 | 205 | entry->align_in_bits = g->pointer_size_bytes * 8; |
| 153 | 206 | assert(child_type->di_type); |
| ... | ... | @@ -165,7 +218,6 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool |
| 165 | 218 | static TypeTableEntry *get_maybe_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *child_type) { |
| 166 | 219 | if (child_type->maybe_parent) { |
| 167 | 220 | TypeTableEntry *entry = child_type->maybe_parent; |
| 168 | | import->block_context->type_table.put(&entry->name, entry); |
| 169 | 221 | return entry; |
| 170 | 222 | } else { |
| 171 | 223 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMaybe); |
| ... | ... | @@ -209,7 +261,6 @@ static TypeTableEntry *get_maybe_type(CodeGen *g, ImportTableEntry *import, Type |
| 209 | 261 | |
| 210 | 262 | entry->data.maybe.child_type = child_type; |
| 211 | 263 | |
| 212 | | import->block_context->type_table.put(&entry->name, entry); |
| 213 | 264 | child_type->maybe_parent = entry; |
| 214 | 265 | return entry; |
| 215 | 266 | } |
| ... | ... | @@ -221,7 +272,6 @@ static TypeTableEntry *get_array_type(CodeGen *g, ImportTableEntry *import, |
| 221 | 272 | auto existing_entry = child_type->arrays_by_size.maybe_get(array_size); |
| 222 | 273 | if (existing_entry) { |
| 223 | 274 | TypeTableEntry *entry = existing_entry->value; |
| 224 | | import->block_context->type_table.put(&entry->name, entry); |
| 225 | 275 | return entry; |
| 226 | 276 | } else { |
| 227 | 277 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray); |
| ... | ... | @@ -237,7 +287,6 @@ static TypeTableEntry *get_array_type(CodeGen *g, ImportTableEntry *import, |
| 237 | 287 | entry->data.array.child_type = child_type; |
| 238 | 288 | entry->data.array.len = array_size; |
| 239 | 289 | |
| 240 | | import->block_context->type_table.put(&entry->name, entry); |
| 241 | 290 | child_type->arrays_by_size.put(array_size, entry); |
| 242 | 291 | return entry; |
| 243 | 292 | } |
| ... | ... | @@ -636,7 +685,165 @@ static void preview_function_labels(CodeGen *g, AstNode *node, FnTableEntry *fn_ |
| 636 | 685 | } |
| 637 | 686 | } |
| 638 | 687 | |
| 639 | | static void resolve_container_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type) { |
| 688 | static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *enum_type) { |
| 689 | assert(enum_type->id == TypeTableEntryIdEnum); |
| 690 | |
| 691 | AstNode *decl_node = enum_type->data.enumeration.decl_node; |
| 692 | |
| 693 | if (enum_type->data.enumeration.embedded_in_current) { |
| 694 | if (!enum_type->data.enumeration.reported_infinite_err) { |
| 695 | enum_type->data.enumeration.reported_infinite_err = true; |
| 696 | add_node_error(g, decl_node, buf_sprintf("enum has infinite size")); |
| 697 | } |
| 698 | return; |
| 699 | } |
| 700 | |
| 701 | if (enum_type->data.enumeration.fields) { |
| 702 | // we already resolved this type. skip |
| 703 | return; |
| 704 | } |
| 705 | |
| 706 | assert(enum_type->di_type); |
| 707 | |
| 708 | int field_count = decl_node->data.struct_decl.fields.length; |
| 709 | |
| 710 | enum_type->data.enumeration.field_count = field_count; |
| 711 | enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); |
| 712 | LLVMZigDIEnumerator **di_enumerators = allocate<LLVMZigDIEnumerator*>(field_count); |
| 713 | |
| 714 | // we possibly allocate too much here since gen_field_count can be lower than field_count. |
| 715 | // the only problem is potential wasted space though. |
| 716 | LLVMZigDIType **union_inner_di_types = allocate<LLVMZigDIType*>(field_count); |
| 717 | |
| 718 | TypeTableEntry *biggest_union_member = nullptr; |
| 719 | uint64_t biggest_align_in_bits = 0; |
| 720 | uint64_t biggest_union_member_size_in_bits = 0; |
| 721 | |
| 722 | // set temporary flag |
| 723 | enum_type->data.enumeration.embedded_in_current = true; |
| 724 | |
| 725 | int gen_field_index = 0; |
| 726 | for (int i = 0; i < field_count; i += 1) { |
| 727 | AstNode *field_node = decl_node->data.struct_decl.fields.at(i); |
| 728 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; |
| 729 | type_enum_field->name = &field_node->data.struct_field.name; |
| 730 | type_enum_field->type_entry = resolve_type(g, field_node->data.struct_field.type, |
| 731 | import, import->block_context, false); |
| 732 | |
| 733 | di_enumerators[i] = LLVMZigCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i); |
| 734 | |
| 735 | if (type_enum_field->type_entry->id == TypeTableEntryIdStruct) { |
| 736 | resolve_struct_type(g, import, type_enum_field->type_entry); |
| 737 | } else if (type_enum_field->type_entry->id == TypeTableEntryIdEnum) { |
| 738 | resolve_enum_type(g, import, type_enum_field->type_entry); |
| 739 | } else if (type_enum_field->type_entry->id == TypeTableEntryIdInvalid) { |
| 740 | enum_type->data.enumeration.is_invalid = true; |
| 741 | continue; |
| 742 | } else if (type_enum_field->type_entry->id == TypeTableEntryIdVoid) { |
| 743 | continue; |
| 744 | } |
| 745 | |
| 746 | union_inner_di_types[gen_field_index] = LLVMZigCreateDebugMemberType(g->dbuilder, |
| 747 | LLVMZigTypeToScope(enum_type->di_type), buf_ptr(type_enum_field->name), |
| 748 | import->di_file, field_node->line + 1, |
| 749 | type_enum_field->type_entry->size_in_bits, |
| 750 | type_enum_field->type_entry->align_in_bits, |
| 751 | 0, 0, type_enum_field->type_entry->di_type); |
| 752 | |
| 753 | biggest_align_in_bits = max(biggest_align_in_bits, type_enum_field->type_entry->align_in_bits); |
| 754 | |
| 755 | if (!biggest_union_member || |
| 756 | type_enum_field->type_entry->size_in_bits > biggest_union_member->size_in_bits) |
| 757 | { |
| 758 | biggest_union_member = type_enum_field->type_entry; |
| 759 | biggest_union_member_size_in_bits = biggest_union_member->size_in_bits; |
| 760 | } |
| 761 | |
| 762 | gen_field_index += 1; |
| 763 | } |
| 764 | |
| 765 | // unset temporary flag |
| 766 | enum_type->data.enumeration.embedded_in_current = false; |
| 767 | |
| 768 | if (!enum_type->data.enumeration.is_invalid) { |
| 769 | uint64_t tag_size_in_bits = get_number_literal_type_unsigned(g, field_count)->size_in_bits; |
| 770 | enum_type->align_in_bits = tag_size_in_bits; |
| 771 | enum_type->size_in_bits = tag_size_in_bits + biggest_union_member_size_in_bits; |
| 772 | TypeTableEntry *tag_type_entry = get_int_type_unsigned(g, field_count); |
| 773 | |
| 774 | if (biggest_union_member) { |
| 775 | // create llvm type for union |
| 776 | LLVMTypeRef union_element_type = biggest_union_member->type_ref; |
| 777 | LLVMTypeRef union_type_ref = LLVMStructType(&union_element_type, 1, false); |
| 778 | |
| 779 | // create llvm type for root struct |
| 780 | LLVMTypeRef root_struct_element_types[] = { |
| 781 | tag_type_entry->type_ref, |
| 782 | union_type_ref, |
| 783 | }; |
| 784 | LLVMStructSetBody(enum_type->type_ref, root_struct_element_types, 2, false); |
| 785 | |
| 786 | // create debug type for tag |
| 787 | LLVMZigDIType *tag_di_type = LLVMZigCreateDebugEnumerationType(g->dbuilder, |
| 788 | LLVMZigTypeToScope(enum_type->di_type), "AnonEnum", import->di_file, decl_node->line + 1, |
| 789 | tag_type_entry->size_in_bits, tag_type_entry->align_in_bits, di_enumerators, field_count, |
| 790 | tag_type_entry->di_type, ""); |
| 791 | |
| 792 | // create debug type for union |
| 793 | LLVMZigDIType *union_di_type = LLVMZigCreateDebugUnionType(g->dbuilder, |
| 794 | LLVMZigTypeToScope(enum_type->di_type), "AnonUnion", import->di_file, decl_node->line + 1, |
| 795 | biggest_union_member->size_in_bits, biggest_align_in_bits, 0, union_inner_di_types, |
| 796 | gen_field_index, 0, ""); |
| 797 | |
| 798 | // create debug types for members of root struct |
| 799 | LLVMZigDIType *tag_member_di_type = LLVMZigCreateDebugMemberType(g->dbuilder, |
| 800 | LLVMZigTypeToScope(enum_type->di_type), "tag_field", |
| 801 | import->di_file, decl_node->line + 1, |
| 802 | tag_type_entry->size_in_bits, |
| 803 | tag_type_entry->align_in_bits, |
| 804 | 0, 0, tag_di_type); |
| 805 | LLVMZigDIType *union_member_di_type = LLVMZigCreateDebugMemberType(g->dbuilder, |
| 806 | LLVMZigTypeToScope(enum_type->di_type), "union_field", |
| 807 | import->di_file, decl_node->line + 1, |
| 808 | biggest_union_member->size_in_bits, |
| 809 | biggest_align_in_bits, |
| 810 | tag_type_entry->size_in_bits, 0, union_di_type); |
| 811 | |
| 812 | // create debug type for root struct |
| 813 | LLVMZigDIType *di_root_members[] = { |
| 814 | tag_member_di_type, |
| 815 | union_member_di_type, |
| 816 | }; |
| 817 | |
| 818 | |
| 819 | LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder, |
| 820 | LLVMZigFileToScope(import->di_file), |
| 821 | buf_ptr(&decl_node->data.struct_decl.name), |
| 822 | import->di_file, decl_node->line + 1, enum_type->size_in_bits, enum_type->align_in_bits, 0, |
| 823 | nullptr, di_root_members, 2, 0, nullptr, ""); |
| 824 | |
| 825 | LLVMZigReplaceTemporary(g->dbuilder, enum_type->di_type, replacement_di_type); |
| 826 | enum_type->di_type = replacement_di_type; |
| 827 | } else { |
| 828 | // create llvm type for root struct |
| 829 | enum_type->type_ref = tag_type_entry->type_ref; |
| 830 | |
| 831 | // create debug type for tag |
| 832 | LLVMZigDIType *tag_di_type = LLVMZigCreateDebugEnumerationType(g->dbuilder, |
| 833 | LLVMZigFileToScope(import->di_file), buf_ptr(&decl_node->data.struct_decl.name), |
| 834 | import->di_file, decl_node->line + 1, |
| 835 | tag_type_entry->size_in_bits, tag_type_entry->align_in_bits, di_enumerators, field_count, |
| 836 | tag_type_entry->di_type, ""); |
| 837 | |
| 838 | LLVMZigReplaceTemporary(g->dbuilder, enum_type->di_type, tag_di_type); |
| 839 | enum_type->di_type = tag_di_type; |
| 840 | |
| 841 | } |
| 842 | |
| 843 | } |
| 844 | } |
| 845 | |
| 846 | static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type) { |
| 640 | 847 | assert(struct_type->id == TypeTableEntryIdStruct); |
| 641 | 848 | |
| 642 | 849 | AstNode *decl_node = struct_type->data.structure.decl_node; |
| ... | ... | @@ -672,7 +879,7 @@ static void resolve_container_type(CodeGen *g, ImportTableEntry *import, TypeTab |
| 672 | 879 | uint64_t first_field_align_in_bits = 0; |
| 673 | 880 | uint64_t offset_in_bits = 0; |
| 674 | 881 | |
| 675 | | // this field should be set to true only during the recursive calls to resolve_container_type |
| 882 | // this field should be set to true only during the recursive calls to resolve_struct_type |
| 676 | 883 | struct_type->data.structure.embedded_in_current = true; |
| 677 | 884 | |
| 678 | 885 | int gen_field_index = 0; |
| ... | ... | @@ -686,7 +893,9 @@ static void resolve_container_type(CodeGen *g, ImportTableEntry *import, TypeTab |
| 686 | 893 | type_struct_field->gen_index = -1; |
| 687 | 894 | |
| 688 | 895 | if (type_struct_field->type_entry->id == TypeTableEntryIdStruct) { |
| 689 | | resolve_container_type(g, import, type_struct_field->type_entry); |
| 896 | resolve_struct_type(g, import, type_struct_field->type_entry); |
| 897 | } else if (type_struct_field->type_entry->id == TypeTableEntryIdEnum) { |
| 898 | resolve_enum_type(g, import, type_struct_field->type_entry); |
| 690 | 899 | } else if (type_struct_field->type_entry->id == TypeTableEntryIdInvalid) { |
| 691 | 900 | struct_type->data.structure.is_invalid = true; |
| 692 | 901 | continue; |
| ... | ... | @@ -903,9 +1112,17 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode |
| 903 | 1112 | { |
| 904 | 1113 | TypeTableEntry *type_entry = node->data.struct_decl.type_entry; |
| 905 | 1114 | |
| 906 | | resolve_container_type(g, import, type_entry); |
| 1115 | // struct/enum member fns will get resolved independently |
| 1116 | |
| 1117 | switch (node->data.struct_decl.kind) { |
| 1118 | case ContainerKindStruct: |
| 1119 | resolve_struct_type(g, import, type_entry); |
| 1120 | break; |
| 1121 | case ContainerKindEnum: |
| 1122 | resolve_enum_type(g, import, type_entry); |
| 1123 | break; |
| 1124 | } |
| 907 | 1125 | |
| 908 | | // struct member fns will get resolved independently |
| 909 | 1126 | break; |
| 910 | 1127 | } |
| 911 | 1128 | case NodeTypeVariableDeclaration: |
| ... | ... | @@ -986,6 +1203,8 @@ static bool num_lit_fits_in_other_type(CodeGen *g, TypeTableEntry *literal_type, |
| 986 | 1203 | case TypeTableEntryIdPointer: |
| 987 | 1204 | case TypeTableEntryIdArray: |
| 988 | 1205 | case TypeTableEntryIdStruct: |
| 1206 | case TypeTableEntryIdEnum: |
| 1207 | case TypeTableEntryIdMetaType: |
| 989 | 1208 | return false; |
| 990 | 1209 | case TypeTableEntryIdInt: |
| 991 | 1210 | if (is_num_lit_unsigned(num_lit)) { |
| ... | ... | @@ -1326,6 +1545,12 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i |
| 1326 | 1545 | buf_ptr(&struct_type->name))); |
| 1327 | 1546 | return_type = g->builtin_types.entry_invalid; |
| 1328 | 1547 | } |
| 1548 | } else if (struct_type->id == TypeTableEntryIdMetaType && |
| 1549 | struct_type->data.meta_type.child_type->id == TypeTableEntryIdEnum) |
| 1550 | { |
| 1551 | //TypeTableEntry *enum_type = struct_type->data.meta_type.child_type; |
| 1552 | |
| 1553 | zig_panic("TODO enum field access"); |
| 1329 | 1554 | } else { |
| 1330 | 1555 | if (struct_type->id != TypeTableEntryIdInvalid) { |
| 1331 | 1556 | add_node_error(g, node, |
| ... | ... | @@ -1421,7 +1646,7 @@ static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, |
| 1421 | 1646 | } else { |
| 1422 | 1647 | TypeTableEntry *container_type = find_container(context, variable_name); |
| 1423 | 1648 | if (container_type) { |
| 1424 | | return container_type; |
| 1649 | return get_meta_type(g, container_type); |
| 1425 | 1650 | } else { |
| 1426 | 1651 | add_node_error(g, node, |
| 1427 | 1652 | buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); |
| ... | ... | @@ -2179,6 +2404,10 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import |
| 2179 | 2404 | fn_table = &struct_type->data.pointer.child_type->data.structure.fn_table; |
| 2180 | 2405 | } else if (struct_type->id == TypeTableEntryIdInvalid) { |
| 2181 | 2406 | return struct_type; |
| 2407 | } else if (struct_type->id == TypeTableEntryIdMetaType && |
| 2408 | struct_type->data.meta_type.child_type->id == TypeTableEntryIdEnum) |
| 2409 | { |
| 2410 | zig_panic("TODO enum initialization"); |
| 2182 | 2411 | } else { |
| 2183 | 2412 | add_node_error(g, fn_ref_expr->data.field_access_expr.struct_expr, |
| 2184 | 2413 | buf_sprintf("member reference base type not struct or enum")); |
| ... | ... | @@ -2846,6 +3075,16 @@ static void collect_type_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode |
| 2846 | 3075 | } |
| 2847 | 3076 | } |
| 2848 | 3077 | |
| 3078 | static TypeTableEntryId container_to_type(ContainerKind kind) { |
| 3079 | switch (kind) { |
| 3080 | case ContainerKindStruct: |
| 3081 | return TypeTableEntryIdStruct; |
| 3082 | case ContainerKindEnum: |
| 3083 | return TypeTableEntryIdEnum; |
| 3084 | } |
| 3085 | zig_unreachable(); |
| 3086 | } |
| 3087 | |
| 2849 | 3088 | static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *node) { |
| 2850 | 3089 | switch (node->type) { |
| 2851 | 3090 | case NodeTypeStructDecl: |
| ... | ... | @@ -2860,11 +3099,20 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast |
| 2860 | 3099 | add_node_error(g, node, |
| 2861 | 3100 | buf_sprintf("redefinition of '%s'", buf_ptr(name))); |
| 2862 | 3101 | } else { |
| 2863 | | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct); |
| 3102 | TypeTableEntryId type_id = container_to_type(node->data.struct_decl.kind); |
| 3103 | TypeTableEntry *entry = new_type_table_entry(type_id); |
| 3104 | switch (node->data.struct_decl.kind) { |
| 3105 | case ContainerKindStruct: |
| 3106 | entry->data.structure.decl_node = node; |
| 3107 | break; |
| 3108 | case ContainerKindEnum: |
| 3109 | entry->data.enumeration.decl_node = node; |
| 3110 | break; |
| 3111 | } |
| 3112 | |
| 2864 | 3113 | entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(name)); |
| 2865 | | entry->data.structure.decl_node = node; |
| 2866 | 3114 | entry->di_type = LLVMZigCreateReplaceableCompositeType(g->dbuilder, |
| 2867 | | LLVMZigTag_DW_structure_type(), buf_ptr(&node->data.struct_decl.name), |
| 3115 | LLVMZigTag_DW_structure_type(), buf_ptr(name), |
| 2868 | 3116 | LLVMZigFileToScope(import->di_file), import->di_file, node->line + 1); |
| 2869 | 3117 | |
| 2870 | 3118 | buf_init_from_buf(&entry->name, name); |