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 {
235235 Buf *name;
236236 TypeTableEntry *type_entry;
237237 uint32_t value;
238 uint32_t gen_index;
238239};
239240
240241enum NodeType {
......@@ -813,6 +814,9 @@ struct TypeTableEntryStruct {
813814 bool reported_infinite_err;
814815 // whether we've finished resolving it
815816 bool complete;
817
818 bool zero_bits_loop_flag;
819 bool zero_bits_known;
816820};
817821
818822struct TypeTableEntryMaybe {
......@@ -840,6 +844,9 @@ struct TypeTableEntryEnum {
840844 bool reported_infinite_err;
841845 // whether we've finished resolving it
842846 bool complete;
847
848 bool zero_bits_loop_flag;
849 bool zero_bits_known;
843850};
844851
845852struct TypeTableEntryEnumTag {
......@@ -862,6 +869,9 @@ struct TypeTableEntryUnion {
862869 bool reported_infinite_err;
863870 // whether we've finished resolving it
864871 bool complete;
872
873 bool zero_bits_loop_flag;
874 bool zero_bits_known;
865875};
866876
867877struct FnGenParamInfo {
src/analyze.cpp+218-84
......@@ -20,6 +20,10 @@ static const size_t default_backward_branch_quota = 1000;
2020static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type);
2121static 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
2327AstNode *first_executing_node(AstNode *node) {
2428 switch (node->type) {
2529 case NodeTypeFnCallExpr:
......@@ -257,6 +261,44 @@ bool type_is_complete(TypeTableEntry *type_entry) {
257261 zig_unreachable();
258262}
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
260302uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry) {
261303 if (type_has_bits(type_entry)) {
262304 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
475517 return entry;
476518 } else {
477519 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray);
478 entry->type_ref = child_type->type_ref ? LLVMArrayType(child_type->type_ref, array_size) : nullptr;
479520 entry->zero_bits = (array_size == 0) || child_type->zero_bits;
480521
481522 buf_resize(&entry->name, 0);
482523 buf_appendf(&entry->name, "[%" PRIu64 "]%s", array_size, buf_ptr(&child_type->name));
483524
484525 if (!entry->zero_bits) {
526 entry->type_ref = child_type->type_ref ? LLVMArrayType(child_type->type_ref, array_size) : nullptr;
527
485528 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref);
486529 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,
507550 entry->data.structure.src_field_count = element_count;
508551 entry->data.structure.gen_field_count = element_count;
509552 entry->data.structure.fields = allocate<TypeStructField>(element_count);
510 entry->data.structure.fields[0].name = buf_create_from_str("ptr");
511 entry->data.structure.fields[0].type_entry = pointer_type;
512 entry->data.structure.fields[0].src_index = 0;
513 entry->data.structure.fields[0].gen_index = 0;
514 entry->data.structure.fields[1].name = buf_create_from_str("len");
515 entry->data.structure.fields[1].type_entry = g->builtin_types.entry_usize;
516 entry->data.structure.fields[1].src_index = 1;
517 entry->data.structure.fields[1].gen_index = 1;
553 entry->data.structure.fields[slice_ptr_index].name = buf_create_from_str("ptr");
554 entry->data.structure.fields[slice_ptr_index].type_entry = pointer_type;
555 entry->data.structure.fields[slice_ptr_index].src_index = slice_ptr_index;
556 entry->data.structure.fields[slice_ptr_index].gen_index = 0;
557 entry->data.structure.fields[slice_len_index].name = buf_create_from_str("len");
558 entry->data.structure.fields[slice_len_index].type_entry = g->builtin_types.entry_usize;
559 entry->data.structure.fields[slice_len_index].src_index = slice_len_index;
560 entry->data.structure.fields[slice_len_index].gen_index = 1;
561
562 assert(type_has_zero_bits_known(child_type));
563 if (child_type->zero_bits) {
564 entry->data.structure.gen_field_count = 1;
565 entry->data.structure.fields[slice_ptr_index].gen_index = SIZE_MAX;
566 entry->data.structure.fields[slice_len_index].gen_index = 0;
567 }
518568}
519569
520570TypeTableEntry *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
535585 entry->type_ref = var_peer->type_ref;
536586 entry->di_type = var_peer->di_type;
537587 entry->data.structure.complete = true;
588 entry->data.structure.zero_bits_known = true;
538589
539590 *parent_pointer = entry;
540591 return entry;
......@@ -544,7 +595,7 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c
544595 // If the child type is []const T then we need to make sure the type ref
545596 // and debug info is the same as if the child type were []T.
546597 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;
548599 assert(ptr_type->id == TypeTableEntryIdPointer);
549600 if (ptr_type->data.pointer.is_const) {
550601 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
560611 buf_appendf(&entry->name, "[]%s", buf_ptr(&child_type->name));
561612
562613 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
569615 if (!entry->type_ref) {
570616 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
582628 };
583629 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
591631 TypeTableEntry *usize_type = g->builtin_types.entry_usize;
592632 uint64_t len_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, usize_type->type_ref);
593633 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
622662 };
623663 LLVMStructSetBody(entry->type_ref, element_types, element_count, false);
624664
625 slice_type_common_init(g, child_type, is_const, entry);
626
627665
628666 uint64_t ptr_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, pointer_type->type_ref);
629667 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
664702
665703
666704 entry->data.structure.complete = true;
705 entry->data.structure.zero_bits_known = true;
667706
668707 *parent_pointer = entry;
669708 return entry;
......@@ -706,6 +745,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
706745 if (table_entry) {
707746 return table_entry->value;
708747 }
748 ensure_complete_type(g, fn_type_id->return_type);
709749
710750 TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn);
711751 fn_type->data.fn.fn_type_id = *fn_type_id;
......@@ -750,7 +790,6 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
750790 // next, loop over the parameters again and compute debug information
751791 // and codegen information
752792 if (!skip_debug_info) {
753 ensure_complete_type(g, fn_type_id->return_type);
754793 bool first_arg_return = !fn_type_id->is_extern && handle_is_ptr(fn_type_id->return_type);
755794 // +1 for maybe making the first argument the return value
756795 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) {
10561095 // if you change this logic you likely must also change similar logic in parseh.cpp
10571096 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
10591102 AstNode *decl_node = enum_type->data.enumeration.decl_node;
10601103
10611104 if (enum_type->data.enumeration.embedded_in_current) {
10621105 if (!enum_type->data.enumeration.reported_infinite_err) {
10631106 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"));
10651108 }
10661109 return;
10671110 }
10681111
1069 if (enum_type->data.enumeration.fields) {
1070 // we already resolved this type. skip
1071 return;
1072 }
1073
1112 assert(!enum_type->data.enumeration.zero_bits_loop_flag);
10741113 assert(decl_node->type == NodeTypeContainerDecl);
10751114 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;
1080 enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count);
1118 assert(enum_type->data.enumeration.fields);
10811119 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.
1084 // the only problem is potential wasted space though.
1085 ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(field_count);
1121 uint32_t gen_field_count = enum_type->data.enumeration.gen_field_count;
1122 ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(gen_field_count);
10861123
10871124 TypeTableEntry *biggest_union_member = nullptr;
10881125 uint64_t biggest_align_in_bits = 0;
......@@ -1094,14 +1131,10 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
10941131 // set temporary flag
10951132 enum_type->data.enumeration.embedded_in_current = true;
10961133
1097 size_t gen_field_index = 0;
10981134 for (uint32_t i = 0; i < field_count; i += 1) {
10991135 AstNode *field_node = decl_node->data.container_decl.fields.at(i);
11001136 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i];
1101 type_enum_field->name = field_node->data.struct_field.name;
1102 TypeTableEntry *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type);
1103 type_enum_field->type_entry = field_type;
1104 type_enum_field->value = i;
1137 TypeTableEntry *field_type = type_enum_field->type_entry;
11051138
11061139 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) {
11201153 assert(debug_size_in_bits > 0);
11211154 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,
11241157 ZigLLVMTypeToScope(enum_type->di_type), buf_ptr(type_enum_field->name),
11251158 import->di_file, field_node->line + 1,
11261159 debug_size_in_bits,
......@@ -1136,8 +1169,6 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
11361169 biggest_union_member = field_type;
11371170 biggest_union_member_size_in_bits = debug_size_in_bits;
11381171 }
1139
1140 gen_field_index += 1;
11411172 }
11421173
11431174 // unset temporary flag
......@@ -1145,7 +1176,6 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
11451176 enum_type->data.enumeration.complete = true;
11461177
11471178 if (!enum_type->data.enumeration.is_invalid) {
1148 enum_type->data.enumeration.gen_field_count = gen_field_index;
11491179 enum_type->data.enumeration.union_type = biggest_union_member;
11501180
11511181 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) {
11761206 ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,
11771207 ZigLLVMTypeToScope(enum_type->di_type), "AnonUnion", import->di_file, decl_node->line + 1,
11781208 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
11811211 // create debug types for members of root struct
11821212 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) {
12331263
12341264 ZigLLVMReplaceTemporary(g->dbuilder, enum_type->di_type, tag_di_type);
12351265 enum_type->di_type = tag_di_type;
1236
12371266 }
1238
12391267 }
12401268}
12411269
......@@ -1244,51 +1272,38 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {
12441272 // parseh.cpp
12451273 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
12471279 AstNode *decl_node = struct_type->data.structure.decl_node;
12481280
12491281 if (struct_type->data.structure.embedded_in_current) {
12501282 struct_type->data.structure.is_invalid = true;
12511283 if (!struct_type->data.structure.reported_infinite_err) {
12521284 struct_type->data.structure.reported_infinite_err = true;
1253 add_node_error(g, decl_node,
1254 buf_sprintf("struct has infinite size"));
1285 add_node_error(g, decl_node, buf_sprintf("struct contains itself"));
12551286 }
12561287 return;
12571288 }
12581289
1259 if (struct_type->data.structure.fields) {
1260 // we already resolved this type. skip
1261 return;
1262 }
1263
1290 assert(!struct_type->data.structure.zero_bits_loop_flag);
1291 assert(struct_type->data.enumeration.fields);
12641292 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;
1270 struct_type->data.structure.fields = allocate<TypeStructField>(field_count);
1294 size_t field_count = struct_type->data.structure.src_field_count;
12711295
1272 // we possibly allocate too much here since gen_field_count can be lower than field_count.
1273 // the only problem is potential wasted space though.
1274 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);
1296 size_t gen_field_count = struct_type->data.structure.gen_field_count;
1297 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(gen_field_count);
12751298
12761299 // this field should be set to true only during the recursive calls to resolve_struct_type
12771300 struct_type->data.structure.embedded_in_current = true;
12781301
12791302 Scope *scope = &struct_type->data.structure.decls_scope->base;
1280 ImportTableEntry *import = get_scope_import(scope);
12811303
1282 size_t gen_field_index = 0;
12831304 for (size_t i = 0; i < field_count; i += 1) {
1284 AstNode *field_node = decl_node->data.container_decl.fields.at(i);
12851305 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
1286 type_struct_field->name = field_node->data.struct_field.name;
1287 TypeTableEntry *field_type = analyze_type_expr(g, scope,
1288 field_node->data.struct_field.type);
1289 type_struct_field->type_entry = field_type;
1290 type_struct_field->src_index = i;
1291 type_struct_field->gen_index = SIZE_MAX;
1306 TypeTableEntry *field_type = type_struct_field->type_entry;
12921307
12931308 ensure_complete_type(g, field_type);
12941309 if (field_type->id == TypeTableEntryIdInvalid) {
......@@ -1299,31 +1314,31 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {
12991314 if (!type_has_bits(field_type))
13001315 continue;
13011316
1302 type_struct_field->gen_index = gen_field_index;
1303
1304 element_types[gen_field_index] = field_type->type_ref;
1305 assert(element_types[gen_field_index]);
1306
1307 gen_field_index += 1;
1317 element_types[type_struct_field->gen_index] = field_type->type_ref;
1318 assert(element_types[type_struct_field->gen_index]);
13081319 }
13091320 struct_type->data.structure.embedded_in_current = false;
1310
1311 struct_type->data.structure.gen_field_count = gen_field_index;
13121321 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;
13151329 return;
13161330 }
1331 assert(struct_type->di_type);
13171332
1318 size_t gen_field_count = gen_field_index;
13191333 LLVMStructSetBody(struct_type->type_ref, element_types, gen_field_count, false);
13201334
13211335 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(gen_field_count);
13221336
1337 ImportTableEntry *import = get_scope_import(scope);
13231338 for (size_t i = 0; i < field_count; i += 1) {
13241339 AstNode *field_node = decl_node->data.container_decl.fields.at(i);
13251340 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;
13271342 if (gen_field_index == SIZE_MAX) {
13281343 continue;
13291344 }
......@@ -1362,13 +1377,122 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {
13621377 ZigLLVMReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type);
13631378 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);
13661381}
13671382
13681383static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
13691384 zig_panic("TODO");
13701385}
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
13721496static void get_fully_qualified_decl_name_internal(Buf *buf, Scope *scope, uint8_t sep) {
13731497 if (!scope)
13741498 return;
......@@ -3064,6 +3188,16 @@ void ensure_complete_type(CodeGen *g, TypeTableEntry *type_entry) {
30643188 }
30653189}
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
30673201bool ir_get_var_is_comptime(VariableTableEntry *var) {
30683202 if (!var->is_comptime)
30693203 return false;
src/analyze.hpp+2
......@@ -54,6 +54,7 @@ bool type_is_codegen_pointer(TypeTableEntry *type);
5454TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry);
5555TypeTableEntry *container_ref_type(TypeTableEntry *type_entry);
5656bool type_is_complete(TypeTableEntry *type_entry);
57bool type_has_zero_bits_known(TypeTableEntry *type_entry);
5758void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry);
5859TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *name);
5960ScopeDecls *get_container_scope(TypeTableEntry *type_entry);
......@@ -75,6 +76,7 @@ AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index);
7576FnTableEntry *scope_get_fn_if_root(Scope *scope);
7677bool type_requires_comptime(TypeTableEntry *type_entry);
7778void ensure_complete_type(CodeGen *g, TypeTableEntry *type_entry);
79void type_ensure_zero_bits_known(CodeGen *g, TypeTableEntry *type_entry);
7880void complete_enum(CodeGen *g, TypeTableEntry *enum_type);
7981bool ir_get_var_is_comptime(VariableTableEntry *var);
8082bool const_values_equal(ConstExprValue *a, ConstExprValue *b);
src/codegen.cpp+14
......@@ -2404,6 +2404,7 @@ static void ir_render(CodeGen *g, FnTableEntry *fn_entry) {
24042404
24052405static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
24062406 TypeTableEntry *canon_type = get_underlying_type(const_val->type);
2407 assert(!canon_type->zero_bits);
24072408
24082409 switch (const_val->special) {
24092410 case ConstValSpecialRuntime:
......@@ -2557,6 +2558,14 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
25572558 } else {
25582559 ConstExprValue *array_const_val = const_val->data.x_ptr.base_ptr;
25592560 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 }
25602569 render_const_val(g, array_const_val);
25612570 render_const_val_global(g, array_const_val);
25622571 TypeTableEntry *usize = g->builtin_types.entry_usize;
......@@ -3369,6 +3378,7 @@ static void define_builtin_types(CodeGen *g) {
33693378 }
33703379 }
33713380 entry->data.enumeration.complete = true;
3381 entry->data.enumeration.zero_bits_known = true;
33723382
33733383 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
33743384 entry->data.enumeration.tag_type = tag_type_entry;
......@@ -3402,6 +3412,7 @@ static void define_builtin_types(CodeGen *g) {
34023412 }
34033413 }
34043414 entry->data.enumeration.complete = true;
3415 entry->data.enumeration.zero_bits_known = true;
34053416
34063417 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
34073418 entry->data.enumeration.tag_type = tag_type_entry;
......@@ -3429,6 +3440,7 @@ static void define_builtin_types(CodeGen *g) {
34293440 }
34303441 }
34313442 entry->data.enumeration.complete = true;
3443 entry->data.enumeration.zero_bits_known = true;
34323444
34333445 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
34343446 entry->data.enumeration.tag_type = tag_type_entry;
......@@ -3456,6 +3468,7 @@ static void define_builtin_types(CodeGen *g) {
34563468 }
34573469 }
34583470 entry->data.enumeration.complete = true;
3471 entry->data.enumeration.zero_bits_known = true;
34593472
34603473 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
34613474 entry->data.enumeration.tag_type = tag_type_entry;
......@@ -3491,6 +3504,7 @@ static void define_builtin_types(CodeGen *g) {
34913504 entry->data.enumeration.fields[5].type_entry = g->builtin_types.entry_void;
34923505
34933506 entry->data.enumeration.complete = true;
3507 entry->data.enumeration.zero_bits_known = true;
34943508
34953509 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
34963510 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,
79417941 case TypeTableEntryIdBoundFn:
79427942 case TypeTableEntryIdEnumTag:
79437943 {
7944 type_ensure_zero_bits_known(ira->codegen, resolved_child_type);
79447945 TypeTableEntry *result_type = get_slice_type(ira->codegen, resolved_child_type, is_const);
79457946 ConstExprValue *out_val = ir_build_const_from(ira, &slice_type_instruction->base,
79467947 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)
717717
718718 enum_type->data.enumeration.gen_field_count = 0;
719719 enum_type->data.enumeration.complete = true;
720 enum_type->data.enumeration.zero_bits_known = true;
720721 enum_type->data.enumeration.tag_type = tag_type_entry;
721722
722723 enum_type->data.enumeration.src_field_count = field_count;
......@@ -937,6 +938,7 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
937938
938939 struct_type->data.structure.gen_field_count = field_count;
939940 struct_type->data.structure.complete = true;
941 struct_type->data.structure.zero_bits_known = true;
940942
941943 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, struct_type->type_ref);
942944 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 {
198198 EmptyStruct2 {}
199199}
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
203211// 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{};
2525fn testPointerToVoidReturnType2() -> &const void {
2626 return &test_pointer_to_void_return_type_x;
2727}
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