authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-28 01:15:09-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-28 01:15:09-05:00
log25a5fc32fe68f911f7ac34e513e98cacb0ca17b1
treef709bc56d497216944224b8a1c3706431e684c27
parent15f843e70f18fe0cd7ee31a67af6eb8d6302dcbc

IR: pass passSliceOfEmptyStructToFn test


8 files changed, 255 insertions(+), 97 deletions(-)

src/all_types.hpp+10
...@@ -235,6 +235,7 @@ struct TypeEnumField {...@@ -235,6 +235,7 @@ struct TypeEnumField {
235 Buf *name;235 Buf *name;
236 TypeTableEntry *type_entry;236 TypeTableEntry *type_entry;
237 uint32_t value;237 uint32_t value;
238 uint32_t gen_index;
238};239};
239240
240enum NodeType {241enum NodeType {
...@@ -813,6 +814,9 @@ struct TypeTableEntryStruct {...@@ -813,6 +814,9 @@ struct TypeTableEntryStruct {
813 bool reported_infinite_err;814 bool reported_infinite_err;
814 // whether we've finished resolving it815 // whether we've finished resolving it
815 bool complete;816 bool complete;
817
818 bool zero_bits_loop_flag;
819 bool zero_bits_known;
816};820};
817821
818struct TypeTableEntryMaybe {822struct TypeTableEntryMaybe {
...@@ -840,6 +844,9 @@ struct TypeTableEntryEnum {...@@ -840,6 +844,9 @@ struct TypeTableEntryEnum {
840 bool reported_infinite_err;844 bool reported_infinite_err;
841 // whether we've finished resolving it845 // whether we've finished resolving it
842 bool complete;846 bool complete;
847
848 bool zero_bits_loop_flag;
849 bool zero_bits_known;
843};850};
844851
845struct TypeTableEntryEnumTag {852struct TypeTableEntryEnumTag {
...@@ -862,6 +869,9 @@ struct TypeTableEntryUnion {...@@ -862,6 +869,9 @@ struct TypeTableEntryUnion {
862 bool reported_infinite_err;869 bool reported_infinite_err;
863 // whether we've finished resolving it870 // whether we've finished resolving it
864 bool complete;871 bool complete;
872
873 bool zero_bits_loop_flag;
874 bool zero_bits_known;
865};875};
866876
867struct FnGenParamInfo {877struct FnGenParamInfo {
src/analyze.cpp+218-84
...@@ -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;
20static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type);20static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type);
21static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type);21static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type);
2222
23static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type);
24static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type);
25static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type);
26
23AstNode *first_executing_node(AstNode *node) {27AstNode *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}
259263
264bool 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
260uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry) {302uint64_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;
480521
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));
483524
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);
487530
...@@ -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}
519569
520TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_const) {570TypeTableEntry *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;
538589
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 ref595 // 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));
561612
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 }
568614
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);
584630
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);
624664
625 slice_type_common_init(g, child_type, is_const, entry);
626
627665
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
664702
665703
666 entry->data.structure.complete = true;704 entry->data.structure.complete = true;
705 entry->data.structure.zero_bits_known = true;
667706
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);
709749
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 information790 // next, loop over the parameters again and compute debug information
751 // and codegen information791 // 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 value794 // +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.cpp1095 // 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);
10581097
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;
10601103
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 }
10681111
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);
10761115
1077 uint32_t field_count = decl_node->data.container_decl.fields.length;1116 uint32_t field_count = enum_type->data.enumeration.src_field_count;
10781117
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);
10821120
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);
10861123
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 flag1131 // set temporary flag
1095 enum_type->data.enumeration.embedded_in_current = true;1132 enum_type->data.enumeration.embedded_in_current = true;
10961133
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;
11051138
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);
11071140
...@@ -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);
11221155
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 }
11421173
1143 // unset temporary flag1174 // 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;
11461177
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;
11501180
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, "");
11801210
1181 // create debug types for members of root struct1211 // 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) {
12331263
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}
12411269
...@@ -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.cpp1272 // parseh.cpp
1245 assert(struct_type->id == TypeTableEntryIdStruct);1273 assert(struct_type->id == TypeTableEntryIdStruct);
12461274
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;
12481280
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 }
12581289
1259 if (struct_type->data.structure.fields) {1290 assert(!struct_type->data.structure.zero_bits_loop_flag);
1260 // we already resolved this type. skip1291 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;
12681293
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);
12711295
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);
12751298
1276 // this field should be set to true only during the recursive calls to resolve_struct_type1299 // 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;
12781301
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);
12811303
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;
12921307
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;
13011316
1302 type_struct_field->gen_index = gen_field_index;1317 element_types[type_struct_field->gen_index] = field_type->type_ref;
13031318 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;
13131322
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);
13171332
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);
13201334
1321 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(gen_field_count);1335 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(gen_field_count);
13221336
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;
13641379
1365 struct_type->zero_bits = (debug_size_in_bits == 0);1380 assert((debug_size_in_bits == 0) == struct_type->zero_bits);
1366}1381}
13671382
1368static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {1383static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
1369 zig_panic("TODO");1384 zig_panic("TODO");
1370}1385}
13711386
1387static 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
1439static 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
1492static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
1493 zig_panic("TODO resolve_union_zero_bits");
1494}
1495
1372static void get_fully_qualified_decl_name_internal(Buf *buf, Scope *scope, uint8_t sep) {1496static 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}
30663190
3191void 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
3067bool ir_get_var_is_comptime(VariableTableEntry *var) {3201bool ir_get_var_is_comptime(VariableTableEntry *var) {
3068 if (!var->is_comptime)3202 if (!var->is_comptime)
3069 return false;3203 return false;
src/analyze.hpp+2
...@@ -54,6 +54,7 @@ bool type_is_codegen_pointer(TypeTableEntry *type);...@@ -54,6 +54,7 @@ bool type_is_codegen_pointer(TypeTableEntry *type);
54TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry);54TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry);
55TypeTableEntry *container_ref_type(TypeTableEntry *type_entry);55TypeTableEntry *container_ref_type(TypeTableEntry *type_entry);
56bool type_is_complete(TypeTableEntry *type_entry);56bool type_is_complete(TypeTableEntry *type_entry);
57bool type_has_zero_bits_known(TypeTableEntry *type_entry);
57void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry);58void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry);
58TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *name);59TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *name);
59ScopeDecls *get_container_scope(TypeTableEntry *type_entry);60ScopeDecls *get_container_scope(TypeTableEntry *type_entry);
...@@ -75,6 +76,7 @@ AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index);...@@ -75,6 +76,7 @@ AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index);
75FnTableEntry *scope_get_fn_if_root(Scope *scope);76FnTableEntry *scope_get_fn_if_root(Scope *scope);
76bool type_requires_comptime(TypeTableEntry *type_entry);77bool type_requires_comptime(TypeTableEntry *type_entry);
77void ensure_complete_type(CodeGen *g, TypeTableEntry *type_entry);78void ensure_complete_type(CodeGen *g, TypeTableEntry *type_entry);
79void type_ensure_zero_bits_known(CodeGen *g, TypeTableEntry *type_entry);
78void complete_enum(CodeGen *g, TypeTableEntry *enum_type);80void complete_enum(CodeGen *g, TypeTableEntry *enum_type);
79bool ir_get_var_is_comptime(VariableTableEntry *var);81bool ir_get_var_is_comptime(VariableTableEntry *var);
80bool const_values_equal(ConstExprValue *a, ConstExprValue *b);82bool const_values_equal(ConstExprValue *a, ConstExprValue *b);
src/codegen.cpp+14
...@@ -2404,6 +2404,7 @@ static void ir_render(CodeGen *g, FnTableEntry *fn_entry) {...@@ -2404,6 +2404,7 @@ static void ir_render(CodeGen *g, FnTableEntry *fn_entry) {
24042404
2405static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {2405static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
2406 TypeTableEntry *canon_type = get_underlying_type(const_val->type);2406 TypeTableEntry *canon_type = get_underlying_type(const_val->type);
2407 assert(!canon_type->zero_bits);
24072408
2408 switch (const_val->special) {2409 switch (const_val->special) {
2409 case ConstValSpecialRuntime:2410 case ConstValSpecialRuntime:
...@@ -2557,6 +2558,14 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -2557,6 +2558,14 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
2557 } else {2558 } else {
2558 ConstExprValue *array_const_val = const_val->data.x_ptr.base_ptr;2559 ConstExprValue *array_const_val = const_val->data.x_ptr.base_ptr;
2559 assert(array_const_val->type->id == TypeTableEntryIdArray);2560 assert(array_const_val->type->id == TypeTableEntryIdArray);
2561 if (array_const_val->type->zero_bits) {
2562 // make this a null pointer
2563 TypeTableEntry *usize_type = g->builtin_types.entry_usize;
2564 const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize_type->type_ref),
2565 const_val->type->type_ref);
2566 render_const_val_global(g, const_val);
2567 return const_val->llvm_value;
2568 }
2560 render_const_val(g, array_const_val);2569 render_const_val(g, array_const_val);
2561 render_const_val_global(g, array_const_val);2570 render_const_val_global(g, array_const_val);
2562 TypeTableEntry *usize = g->builtin_types.entry_usize;2571 TypeTableEntry *usize = g->builtin_types.entry_usize;
...@@ -3369,6 +3378,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3369,6 +3378,7 @@ static void define_builtin_types(CodeGen *g) {
3369 }3378 }
3370 }3379 }
3371 entry->data.enumeration.complete = true;3380 entry->data.enumeration.complete = true;
3381 entry->data.enumeration.zero_bits_known = true;
33723382
3373 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);3383 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
3374 entry->data.enumeration.tag_type = tag_type_entry;3384 entry->data.enumeration.tag_type = tag_type_entry;
...@@ -3402,6 +3412,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3402,6 +3412,7 @@ static void define_builtin_types(CodeGen *g) {
3402 }3412 }
3403 }3413 }
3404 entry->data.enumeration.complete = true;3414 entry->data.enumeration.complete = true;
3415 entry->data.enumeration.zero_bits_known = true;
34053416
3406 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);3417 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
3407 entry->data.enumeration.tag_type = tag_type_entry;3418 entry->data.enumeration.tag_type = tag_type_entry;
...@@ -3429,6 +3440,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3429,6 +3440,7 @@ static void define_builtin_types(CodeGen *g) {
3429 }3440 }
3430 }3441 }
3431 entry->data.enumeration.complete = true;3442 entry->data.enumeration.complete = true;
3443 entry->data.enumeration.zero_bits_known = true;
34323444
3433 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);3445 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
3434 entry->data.enumeration.tag_type = tag_type_entry;3446 entry->data.enumeration.tag_type = tag_type_entry;
...@@ -3456,6 +3468,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3456,6 +3468,7 @@ static void define_builtin_types(CodeGen *g) {
3456 }3468 }
3457 }3469 }
3458 entry->data.enumeration.complete = true;3470 entry->data.enumeration.complete = true;
3471 entry->data.enumeration.zero_bits_known = true;
34593472
3460 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);3473 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
3461 entry->data.enumeration.tag_type = tag_type_entry;3474 entry->data.enumeration.tag_type = tag_type_entry;
...@@ -3491,6 +3504,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3491,6 +3504,7 @@ static void define_builtin_types(CodeGen *g) {
3491 entry->data.enumeration.fields[5].type_entry = g->builtin_types.entry_void;3504 entry->data.enumeration.fields[5].type_entry = g->builtin_types.entry_void;
34923505
3493 entry->data.enumeration.complete = true;3506 entry->data.enumeration.complete = true;
3507 entry->data.enumeration.zero_bits_known = true;
34943508
3495 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);3509 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
3496 entry->data.enumeration.tag_type = tag_type_entry;3510 entry->data.enumeration.tag_type = tag_type_entry;
src/ir.cpp+1
...@@ -7941,6 +7941,7 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,...@@ -7941,6 +7941,7 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,
7941 case TypeTableEntryIdBoundFn:7941 case TypeTableEntryIdBoundFn:
7942 case TypeTableEntryIdEnumTag:7942 case TypeTableEntryIdEnumTag:
7943 {7943 {
7944 type_ensure_zero_bits_known(ira->codegen, resolved_child_type);
7944 TypeTableEntry *result_type = get_slice_type(ira->codegen, resolved_child_type, is_const);7945 TypeTableEntry *result_type = get_slice_type(ira->codegen, resolved_child_type, is_const);
7945 ConstExprValue *out_val = ir_build_const_from(ira, &slice_type_instruction->base,7946 ConstExprValue *out_val = ir_build_const_from(ira, &slice_type_instruction->base,
7946 child_type->value.depends_on_compile_var);7947 child_type->value.depends_on_compile_var);
src/parseh.cpp+2
...@@ -717,6 +717,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)...@@ -717,6 +717,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)
717717
718 enum_type->data.enumeration.gen_field_count = 0;718 enum_type->data.enumeration.gen_field_count = 0;
719 enum_type->data.enumeration.complete = true;719 enum_type->data.enumeration.complete = true;
720 enum_type->data.enumeration.zero_bits_known = true;
720 enum_type->data.enumeration.tag_type = tag_type_entry;721 enum_type->data.enumeration.tag_type = tag_type_entry;
721722
722 enum_type->data.enumeration.src_field_count = field_count;723 enum_type->data.enumeration.src_field_count = field_count;
...@@ -937,6 +938,7 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_...@@ -937,6 +938,7 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
937938
938 struct_type->data.structure.gen_field_count = field_count;939 struct_type->data.structure.gen_field_count = field_count;
939 struct_type->data.structure.complete = true;940 struct_type->data.structure.complete = true;
941 struct_type->data.structure.zero_bits_known = true;
940942
941 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, struct_type->type_ref);943 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, struct_type->type_ref);
942 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, struct_type->type_ref);944 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, struct_type->type_ref);
test/cases/struct.zig+8
...@@ -198,6 +198,14 @@ fn testReturnEmptyStructFromFn() -> EmptyStruct2 {...@@ -198,6 +198,14 @@ fn testReturnEmptyStructFromFn() -> EmptyStruct2 {
198 EmptyStruct2 {}198 EmptyStruct2 {}
199}199}
200200
201fn passSliceOfEmptyStructToFn() {
202 @setFnTest(this);
203
204 assert(testPassSliceOfEmptyStructToFn([]EmptyStruct2{ EmptyStruct2{} }) == 1);
205}
206fn testPassSliceOfEmptyStructToFn(slice: []EmptyStruct2) -> usize {
207 slice.len
208}
201209
202210
203// TODO const assert = @import("std").debug.assert;211// TODO const assert = @import("std").debug.assert;
test/self_hosted.zig-13
...@@ -25,16 +25,3 @@ const test_pointer_to_void_return_type_x = void{};...@@ -25,16 +25,3 @@ const test_pointer_to_void_return_type_x = void{};
25fn testPointerToVoidReturnType2() -> &const void {25fn testPointerToVoidReturnType2() -> &const void {
26 return &test_pointer_to_void_return_type_x;26 return &test_pointer_to_void_return_type_x;
27}27}
28
29
30// TODO not passing (goes in struct.zig)
31fn passSliceOfEmptyStructToFn() {
32 @setFnTest(this);
33
34 assert(testPassSliceOfEmptyStructToFn([]EmptyStruct2{ EmptyStruct2{} }) == 1);
35}
36fn testPassSliceOfEmptyStructToFn(slice: []EmptyStruct2) -> usize {
37 slice.len
38}
39
40