authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-11 00:25:17-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-11 00:25:17-07:00
log2061cd50c0ec6cfcac60ea98f49e4333a4f508f1
tree7c119d25686d9ad86282ec58c8e1a43698f27e7f
parentb147ff5b60ebb32ec5a3c1f6da82601201d5ad9a

resolve enum types and emit debug info


4 files changed, 351 insertions(+), 17 deletions(-)

src/all_types.hpp+28-1
...@@ -705,8 +705,32 @@ struct TypeTableEntryMaybe {...@@ -705,8 +705,32 @@ struct TypeTableEntryMaybe {
705 TypeTableEntry *child_type;705 TypeTableEntry *child_type;
706};706};
707707
708struct TypeTableEntryMetaType {
709 TypeTableEntry *child_type;
710};
711
712struct TypeEnumField {
713 Buf *name;
714 TypeTableEntry *type_entry;
715};
716
717struct TypeTableEntryEnum {
718 AstNode *decl_node;
719 int field_count;
720 TypeEnumField *fields;
721 bool is_invalid; // true if any fields are invalid
722
723 // reminder: hash tables must be initialized before use
724 HashMap<Buf *, FnTableEntry *, buf_hash, buf_eql_buf> fn_table;
725
726 // set this flag temporarily to detect infinite loops
727 bool embedded_in_current;
728 bool reported_infinite_err;
729};
730
708enum TypeTableEntryId {731enum TypeTableEntryId {
709 TypeTableEntryIdInvalid,732 TypeTableEntryIdInvalid,
733 TypeTableEntryIdMetaType,
710 TypeTableEntryIdVoid,734 TypeTableEntryIdVoid,
711 TypeTableEntryIdBool,735 TypeTableEntryIdBool,
712 TypeTableEntryIdUnreachable,736 TypeTableEntryIdUnreachable,
...@@ -717,6 +741,7 @@ enum TypeTableEntryId {...@@ -717,6 +741,7 @@ enum TypeTableEntryId {
717 TypeTableEntryIdStruct,741 TypeTableEntryIdStruct,
718 TypeTableEntryIdNumberLiteral,742 TypeTableEntryIdNumberLiteral,
719 TypeTableEntryIdMaybe,743 TypeTableEntryIdMaybe,
744 TypeTableEntryIdEnum,
720};745};
721746
722struct TypeTableEntry {747struct TypeTableEntry {
...@@ -736,6 +761,8 @@ struct TypeTableEntry {...@@ -736,6 +761,8 @@ struct TypeTableEntry {
736 TypeTableEntryStruct structure;761 TypeTableEntryStruct structure;
737 TypeTableEntryNumLit num_lit;762 TypeTableEntryNumLit num_lit;
738 TypeTableEntryMaybe maybe;763 TypeTableEntryMaybe maybe;
764 TypeTableEntryEnum enumeration;
765 TypeTableEntryMetaType meta_type;
739 } data;766 } data;
740767
741 // use these fields to make sure we don't duplicate type table entries for the same type768 // use these fields to make sure we don't duplicate type table entries for the same type
...@@ -743,7 +770,7 @@ struct TypeTableEntry {...@@ -743,7 +770,7 @@ struct TypeTableEntry {
743 TypeTableEntry *unknown_size_array_parent[2][2]; // 0 - const. 1 - noalias770 TypeTableEntry *unknown_size_array_parent[2][2]; // 0 - const. 1 - noalias
744 HashMap<uint64_t, TypeTableEntry *, uint64_hash, uint64_eq> arrays_by_size;771 HashMap<uint64_t, TypeTableEntry *, uint64_hash, uint64_eq> arrays_by_size;
745 TypeTableEntry *maybe_parent;772 TypeTableEntry *maybe_parent;
746773 TypeTableEntry *meta_parent;
747};774};
748775
749struct ImporterInfo {776struct ImporterInfo {
src/analyze.cpp+264-16
...@@ -18,6 +18,7 @@ static TypeTableEntry *eval_const_expr(CodeGen *g, BlockContext *context,...@@ -18,6 +18,7 @@ static TypeTableEntry *eval_const_expr(CodeGen *g, BlockContext *context,
18static void collect_type_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *type_node, TopLevelDecl *decl_node);18static void collect_type_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *type_node, TopLevelDecl *decl_node);
19static VariableTableEntry *analyze_variable_declaration(CodeGen *g, ImportTableEntry *import,19static VariableTableEntry *analyze_variable_declaration(CodeGen *g, ImportTableEntry *import,
20 BlockContext *context, TypeTableEntry *expected_type, AstNode *node);20 BlockContext *context, TypeTableEntry *expected_type, AstNode *node);
21static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type);
2122
22static AstNode *first_executing_node(AstNode *node) {23static AstNode *first_executing_node(AstNode *node) {
23 switch (node->type) {24 switch (node->type) {
...@@ -116,8 +117,27 @@ TypeTableEntry *new_type_table_entry(TypeTableEntryId id) {...@@ -116,8 +117,27 @@ TypeTableEntry *new_type_table_entry(TypeTableEntryId id) {
116 entry->arrays_by_size.init(2);117 entry->arrays_by_size.init(2);
117 entry->id = id;118 entry->id = id;
118119
119 if (id == TypeTableEntryIdStruct) {120 switch (id) {
120 entry->data.structure.fn_table.init(8);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 }
122142
123 return entry;143 return entry;
...@@ -139,6 +159,35 @@ static TypeTableEntry *get_number_literal_type_unsigned(CodeGen *g, uint64_t x)...@@ -139,6 +159,35 @@ static TypeTableEntry *get_number_literal_type_unsigned(CodeGen *g, uint64_t x)
139 return g->num_lit_types[get_number_literal_kind_unsigned(x)];159 return g->num_lit_types[get_number_literal_kind_unsigned(x)];
140}160}
141161
162static 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
177static 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
142TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const, bool is_noalias) {191TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const, bool is_noalias) {
143 TypeTableEntry **parent_pointer = &child_type->pointer_parent[(is_const ? 1 : 0)][(is_noalias ? 1 : 0)];192 TypeTableEntry **parent_pointer = &child_type->pointer_parent[(is_const ? 1 : 0)][(is_noalias ? 1 : 0)];
144 if (*parent_pointer) {193 if (*parent_pointer) {
...@@ -146,8 +195,12 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool...@@ -146,8 +195,12 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool
146 } else {195 } else {
147 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPointer);196 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPointer);
148 entry->type_ref = LLVMPointerType(child_type->type_ref, 0);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 buf_resize(&entry->name, 0);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 entry->size_in_bits = g->pointer_size_bytes * 8;204 entry->size_in_bits = g->pointer_size_bytes * 8;
152 entry->align_in_bits = g->pointer_size_bytes * 8;205 entry->align_in_bits = g->pointer_size_bytes * 8;
153 assert(child_type->di_type);206 assert(child_type->di_type);
...@@ -165,7 +218,6 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool...@@ -165,7 +218,6 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool
165static TypeTableEntry *get_maybe_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *child_type) {218static TypeTableEntry *get_maybe_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *child_type) {
166 if (child_type->maybe_parent) {219 if (child_type->maybe_parent) {
167 TypeTableEntry *entry = child_type->maybe_parent;220 TypeTableEntry *entry = child_type->maybe_parent;
168 import->block_context->type_table.put(&entry->name, entry);
169 return entry;221 return entry;
170 } else {222 } else {
171 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMaybe);223 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMaybe);
...@@ -209,7 +261,6 @@ static TypeTableEntry *get_maybe_type(CodeGen *g, ImportTableEntry *import, Type...@@ -209,7 +261,6 @@ static TypeTableEntry *get_maybe_type(CodeGen *g, ImportTableEntry *import, Type
209261
210 entry->data.maybe.child_type = child_type;262 entry->data.maybe.child_type = child_type;
211263
212 import->block_context->type_table.put(&entry->name, entry);
213 child_type->maybe_parent = entry;264 child_type->maybe_parent = entry;
214 return entry;265 return entry;
215 }266 }
...@@ -221,7 +272,6 @@ static TypeTableEntry *get_array_type(CodeGen *g, ImportTableEntry *import,...@@ -221,7 +272,6 @@ static TypeTableEntry *get_array_type(CodeGen *g, ImportTableEntry *import,
221 auto existing_entry = child_type->arrays_by_size.maybe_get(array_size);272 auto existing_entry = child_type->arrays_by_size.maybe_get(array_size);
222 if (existing_entry) {273 if (existing_entry) {
223 TypeTableEntry *entry = existing_entry->value;274 TypeTableEntry *entry = existing_entry->value;
224 import->block_context->type_table.put(&entry->name, entry);
225 return entry;275 return entry;
226 } else {276 } else {
227 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray);277 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray);
...@@ -237,7 +287,6 @@ static TypeTableEntry *get_array_type(CodeGen *g, ImportTableEntry *import,...@@ -237,7 +287,6 @@ static TypeTableEntry *get_array_type(CodeGen *g, ImportTableEntry *import,
237 entry->data.array.child_type = child_type;287 entry->data.array.child_type = child_type;
238 entry->data.array.len = array_size;288 entry->data.array.len = array_size;
239289
240 import->block_context->type_table.put(&entry->name, entry);
241 child_type->arrays_by_size.put(array_size, entry);290 child_type->arrays_by_size.put(array_size, entry);
242 return entry;291 return entry;
243 }292 }
...@@ -636,7 +685,165 @@ static void preview_function_labels(CodeGen *g, AstNode *node, FnTableEntry *fn_...@@ -636,7 +685,165 @@ static void preview_function_labels(CodeGen *g, AstNode *node, FnTableEntry *fn_
636 }685 }
637}686}
638687
639static void resolve_container_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type) {688static 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
846static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type) {
640 assert(struct_type->id == TypeTableEntryIdStruct);847 assert(struct_type->id == TypeTableEntryIdStruct);
641848
642 AstNode *decl_node = struct_type->data.structure.decl_node;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,7 +879,7 @@ static void resolve_container_type(CodeGen *g, ImportTableEntry *import, TypeTab
672 uint64_t first_field_align_in_bits = 0;879 uint64_t first_field_align_in_bits = 0;
673 uint64_t offset_in_bits = 0;880 uint64_t offset_in_bits = 0;
674881
675 // this field should be set to true only during the recursive calls to resolve_container_type882 // this field should be set to true only during the recursive calls to resolve_struct_type
676 struct_type->data.structure.embedded_in_current = true;883 struct_type->data.structure.embedded_in_current = true;
677884
678 int gen_field_index = 0;885 int gen_field_index = 0;
...@@ -686,7 +893,9 @@ static void resolve_container_type(CodeGen *g, ImportTableEntry *import, TypeTab...@@ -686,7 +893,9 @@ static void resolve_container_type(CodeGen *g, ImportTableEntry *import, TypeTab
686 type_struct_field->gen_index = -1;893 type_struct_field->gen_index = -1;
687894
688 if (type_struct_field->type_entry->id == TypeTableEntryIdStruct) {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 } else if (type_struct_field->type_entry->id == TypeTableEntryIdInvalid) {899 } else if (type_struct_field->type_entry->id == TypeTableEntryIdInvalid) {
691 struct_type->data.structure.is_invalid = true;900 struct_type->data.structure.is_invalid = true;
692 continue;901 continue;
...@@ -903,9 +1112,17 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode...@@ -903,9 +1112,17 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
903 {1112 {
904 TypeTableEntry *type_entry = node->data.struct_decl.type_entry;1113 TypeTableEntry *type_entry = node->data.struct_decl.type_entry;
9051114
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 }
9071125
908 // struct member fns will get resolved independently
909 break;1126 break;
910 }1127 }
911 case NodeTypeVariableDeclaration:1128 case NodeTypeVariableDeclaration:
...@@ -986,6 +1203,8 @@ static bool num_lit_fits_in_other_type(CodeGen *g, TypeTableEntry *literal_type,...@@ -986,6 +1203,8 @@ static bool num_lit_fits_in_other_type(CodeGen *g, TypeTableEntry *literal_type,
986 case TypeTableEntryIdPointer:1203 case TypeTableEntryIdPointer:
987 case TypeTableEntryIdArray:1204 case TypeTableEntryIdArray:
988 case TypeTableEntryIdStruct:1205 case TypeTableEntryIdStruct:
1206 case TypeTableEntryIdEnum:
1207 case TypeTableEntryIdMetaType:
989 return false;1208 return false;
990 case TypeTableEntryIdInt:1209 case TypeTableEntryIdInt:
991 if (is_num_lit_unsigned(num_lit)) {1210 if (is_num_lit_unsigned(num_lit)) {
...@@ -1326,6 +1545,12 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i...@@ -1326,6 +1545,12 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
1326 buf_ptr(&struct_type->name)));1545 buf_ptr(&struct_type->name)));
1327 return_type = g->builtin_types.entry_invalid;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 } else {1554 } else {
1330 if (struct_type->id != TypeTableEntryIdInvalid) {1555 if (struct_type->id != TypeTableEntryIdInvalid) {
1331 add_node_error(g, node,1556 add_node_error(g, node,
...@@ -1421,7 +1646,7 @@ static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import,...@@ -1421,7 +1646,7 @@ static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import,
1421 } else {1646 } else {
1422 TypeTableEntry *container_type = find_container(context, variable_name);1647 TypeTableEntry *container_type = find_container(context, variable_name);
1423 if (container_type) {1648 if (container_type) {
1424 return container_type;1649 return get_meta_type(g, container_type);
1425 } else {1650 } else {
1426 add_node_error(g, node,1651 add_node_error(g, node,
1427 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));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,6 +2404,10 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import
2179 fn_table = &struct_type->data.pointer.child_type->data.structure.fn_table;2404 fn_table = &struct_type->data.pointer.child_type->data.structure.fn_table;
2180 } else if (struct_type->id == TypeTableEntryIdInvalid) {2405 } else if (struct_type->id == TypeTableEntryIdInvalid) {
2181 return struct_type;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 } else {2411 } else {
2183 add_node_error(g, fn_ref_expr->data.field_access_expr.struct_expr,2412 add_node_error(g, fn_ref_expr->data.field_access_expr.struct_expr,
2184 buf_sprintf("member reference base type not struct or enum"));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,6 +3075,16 @@ static void collect_type_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode
2846 }3075 }
2847}3076}
28483077
3078static 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
2849static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *node) {3088static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *node) {
2850 switch (node->type) {3089 switch (node->type) {
2851 case NodeTypeStructDecl:3090 case NodeTypeStructDecl:
...@@ -2860,11 +3099,20 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast...@@ -2860,11 +3099,20 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
2860 add_node_error(g, node,3099 add_node_error(g, node,
2861 buf_sprintf("redefinition of '%s'", buf_ptr(name)));3100 buf_sprintf("redefinition of '%s'", buf_ptr(name)));
2862 } else {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 entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(name));3113 entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(name));
2865 entry->data.structure.decl_node = node;
2866 entry->di_type = LLVMZigCreateReplaceableCompositeType(g->dbuilder,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 LLVMZigFileToScope(import->di_file), import->di_file, node->line + 1);3116 LLVMZigFileToScope(import->di_file), import->di_file, node->line + 1);
28693117
2870 buf_init_from_buf(&entry->name, name);3118 buf_init_from_buf(&entry->name, name);
src/zig_llvm.cpp+46
...@@ -161,6 +161,32 @@ LLVMZigDIType *LLVMZigCreateDebugArrayType(LLVMZigDIBuilder *dibuilder, uint64_t...@@ -161,6 +161,32 @@ LLVMZigDIType *LLVMZigCreateDebugArrayType(LLVMZigDIBuilder *dibuilder, uint64_t
161 return reinterpret_cast<LLVMZigDIType*>(di_type);161 return reinterpret_cast<LLVMZigDIType*>(di_type);
162}162}
163163
164LLVMZigDIEnumerator *LLVMZigCreateDebugEnumerator(LLVMZigDIBuilder *dibuilder, const char *name, int64_t val) {
165 DIEnumerator *di_enumerator = reinterpret_cast<DIBuilder*>(dibuilder)->createEnumerator(name, val);
166 return reinterpret_cast<LLVMZigDIEnumerator*>(di_enumerator);
167}
168
169LLVMZigDIType *LLVMZigCreateDebugEnumerationType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,
170 const char *name, LLVMZigDIFile *file, unsigned line_number, uint64_t size_in_bits,
171 uint64_t align_in_bits, LLVMZigDIEnumerator **enumerator_array, int enumerator_array_len,
172 LLVMZigDIType *underlying_type, const char *unique_id)
173{
174 SmallVector<Metadata *, 8> fields;
175 for (int i = 0; i < enumerator_array_len; i += 1) {
176 DIEnumerator *dienumerator = reinterpret_cast<DIEnumerator*>(enumerator_array[i]);
177 fields.push_back(dienumerator);
178 }
179 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createEnumerationType(
180 reinterpret_cast<DIScope*>(scope),
181 name,
182 reinterpret_cast<DIFile*>(file),
183 line_number, size_in_bits, align_in_bits,
184 reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields),
185 reinterpret_cast<DIType*>(underlying_type),
186 unique_id);
187 return reinterpret_cast<LLVMZigDIType*>(di_type);
188}
189
164LLVMZigDIType *LLVMZigCreateDebugMemberType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,190LLVMZigDIType *LLVMZigCreateDebugMemberType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,
165 const char *name, LLVMZigDIFile *file, unsigned line, uint64_t size_in_bits,191 const char *name, LLVMZigDIFile *file, unsigned line, uint64_t size_in_bits,
166 uint64_t align_in_bits, uint64_t offset_in_bits, unsigned flags, LLVMZigDIType *type)192 uint64_t align_in_bits, uint64_t offset_in_bits, unsigned flags, LLVMZigDIType *type)
...@@ -174,6 +200,26 @@ LLVMZigDIType *LLVMZigCreateDebugMemberType(LLVMZigDIBuilder *dibuilder, LLVMZig...@@ -174,6 +200,26 @@ LLVMZigDIType *LLVMZigCreateDebugMemberType(LLVMZigDIBuilder *dibuilder, LLVMZig
174 return reinterpret_cast<LLVMZigDIType*>(di_type);200 return reinterpret_cast<LLVMZigDIType*>(di_type);
175}201}
176202
203LLVMZigDIType *LLVMZigCreateDebugUnionType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,
204 const char *name, LLVMZigDIFile *file, unsigned line_number, uint64_t size_in_bits,
205 uint64_t align_in_bits, unsigned flags, LLVMZigDIType **types_array, int types_array_len,
206 unsigned run_time_lang, const char *unique_id)
207{
208 SmallVector<Metadata *, 8> fields;
209 for (int i = 0; i < types_array_len; i += 1) {
210 DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
211 fields.push_back(ditype);
212 }
213 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createUnionType(
214 reinterpret_cast<DIScope*>(scope),
215 name,
216 reinterpret_cast<DIFile*>(file),
217 line_number, size_in_bits, align_in_bits, flags,
218 reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields),
219 run_time_lang, unique_id);
220 return reinterpret_cast<LLVMZigDIType*>(di_type);
221}
222
177LLVMZigDIType *LLVMZigCreateDebugStructType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,223LLVMZigDIType *LLVMZigCreateDebugStructType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,
178 const char *name, LLVMZigDIFile *file, unsigned line_number, uint64_t size_in_bits,224 const char *name, LLVMZigDIFile *file, unsigned line_number, uint64_t size_in_bits,
179 uint64_t align_in_bits, unsigned flags, LLVMZigDIType *derived_from, 225 uint64_t align_in_bits, unsigned flags, LLVMZigDIType *derived_from,
src/zig_llvm.hpp+13
...@@ -24,6 +24,7 @@ struct LLVMZigDISubprogram;...@@ -24,6 +24,7 @@ struct LLVMZigDISubprogram;
24struct LLVMZigDISubroutineType;24struct LLVMZigDISubroutineType;
25struct LLVMZigDILocalVariable;25struct LLVMZigDILocalVariable;
26struct LLVMZigDILocation;26struct LLVMZigDILocation;
27struct LLVMZigDIEnumerator;
27struct LLVMZigInsertionPoint;28struct LLVMZigInsertionPoint;
2829
29void LLVMZigInitializeLoopStrengthReducePass(LLVMPassRegistryRef R);30void LLVMZigInitializeLoopStrengthReducePass(LLVMPassRegistryRef R);
...@@ -49,12 +50,24 @@ LLVMZigDIType *LLVMZigCreateDebugArrayType(LLVMZigDIBuilder *dibuilder,...@@ -49,12 +50,24 @@ LLVMZigDIType *LLVMZigCreateDebugArrayType(LLVMZigDIBuilder *dibuilder,
49 uint64_t size_in_bits, uint64_t align_in_bits, LLVMZigDIType *elem_type,50 uint64_t size_in_bits, uint64_t align_in_bits, LLVMZigDIType *elem_type,
50 int elem_count);51 int elem_count);
5152
53LLVMZigDIEnumerator *LLVMZigCreateDebugEnumerator(LLVMZigDIBuilder *dibuilder, const char *name, int64_t val);
54
55LLVMZigDIType *LLVMZigCreateDebugEnumerationType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,
56 const char *name, LLVMZigDIFile *file, unsigned line_number, uint64_t size_in_bits,
57 uint64_t align_in_bits, LLVMZigDIEnumerator **enumerator_array, int enumerator_array_len,
58 LLVMZigDIType *underlying_type, const char *unique_id);
59
52LLVMZigDIType *LLVMZigCreateDebugStructType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,60LLVMZigDIType *LLVMZigCreateDebugStructType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,
53 const char *name, LLVMZigDIFile *file, unsigned line_number, uint64_t size_in_bits,61 const char *name, LLVMZigDIFile *file, unsigned line_number, uint64_t size_in_bits,
54 uint64_t align_in_bits, unsigned flags, LLVMZigDIType *derived_from, 62 uint64_t align_in_bits, unsigned flags, LLVMZigDIType *derived_from,
55 LLVMZigDIType **types_array, int types_array_len, unsigned run_time_lang, LLVMZigDIType *vtable_holder,63 LLVMZigDIType **types_array, int types_array_len, unsigned run_time_lang, LLVMZigDIType *vtable_holder,
56 const char *unique_id);64 const char *unique_id);
5765
66LLVMZigDIType *LLVMZigCreateDebugUnionType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,
67 const char *name, LLVMZigDIFile *file, unsigned line_number, uint64_t size_in_bits,
68 uint64_t align_in_bits, unsigned flags, LLVMZigDIType **types_array, int types_array_len,
69 unsigned run_time_lang, const char *unique_id);
70
58LLVMZigDIType *LLVMZigCreateDebugMemberType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,71LLVMZigDIType *LLVMZigCreateDebugMemberType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,
59 const char *name, LLVMZigDIFile *file, unsigned line, uint64_t size_in_bits,72 const char *name, LLVMZigDIFile *file, unsigned line, uint64_t size_in_bits,
60 uint64_t align_in_bits, uint64_t offset_in_bits, unsigned flags, LLVMZigDIType *type);73 uint64_t align_in_bits, uint64_t offset_in_bits, unsigned flags, LLVMZigDIType *type);