authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-03 00:42:24-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-03 02:01:42-07:00
logb28f7d080886ab8347d96899b907e8111fd15e2b
tree9655a16a719a3a5ef4e69bf25e2e986391447a3d
parentb04e64d300b8531c0e84c376d484a62aa9f92614

types sized and aligned with LLVM target data layout API


6 files changed, 434 insertions(+), 253 deletions(-)

src/all_types.hpp+9-3
......@@ -807,6 +807,11 @@ struct TypeTableEntryPointer {
807807
808808struct TypeTableEntryInt {
809809 bool is_signed;
810 int bit_count;
811};
812
813struct TypeTableEntryFloat {
814 int bit_count;
810815};
811816
812817struct TypeTableEntryArray {
......@@ -910,17 +915,17 @@ enum TypeTableEntryId {
910915
911916struct TypeTableEntry {
912917 TypeTableEntryId id;
918 Buf name;
913919
914920 LLVMTypeRef type_ref;
915921 LLVMZigDIType *di_type;
916 uint64_t size_in_bits;
917 uint64_t align_in_bits;
918922
919 Buf name;
923 bool zero_bits;
920924
921925 union {
922926 TypeTableEntryPointer pointer;
923927 TypeTableEntryInt integral;
928 TypeTableEntryFloat floating;
924929 TypeTableEntryArray array;
925930 TypeTableEntryStruct structure;
926931 TypeTableEntryMaybe maybe;
......@@ -988,6 +993,7 @@ enum BuiltinFnId {
988993 BuiltinFnIdMemcpy,
989994 BuiltinFnIdMemset,
990995 BuiltinFnIdSizeof,
996 BuiltinFnIdAlignof,
991997 BuiltinFnIdMaxValue,
992998 BuiltinFnIdMinValue,
993999 BuiltinFnIdMemberCount,
src/analyze.cpp+287-155
......@@ -200,27 +200,21 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool
200200 TypeTableEntry *canon_child_type = get_underlying_type(child_type);
201201 assert(canon_child_type->id != TypeTableEntryIdInvalid);
202202
203 bool zero_bits;
204 if (canon_child_type->size_in_bits == 0) {
205 if (canon_child_type->id == TypeTableEntryIdStruct) {
206 zero_bits = canon_child_type->data.structure.complete;
207 } else if (canon_child_type->id == TypeTableEntryIdEnum) {
208 zero_bits = canon_child_type->data.enumeration.complete;
209 } else {
210 zero_bits = true;
211 }
203
204 if (type_is_complete(canon_child_type)) {
205 entry->zero_bits = !type_has_bits(canon_child_type);
212206 } else {
213 zero_bits = false;
207 entry->zero_bits = false;
214208 }
215209
216 if (!zero_bits) {
210 if (!entry->zero_bits) {
217211 entry->type_ref = LLVMPointerType(child_type->type_ref, 0);
218212
219 entry->size_in_bits = g->pointer_size_bytes * 8;
220 entry->align_in_bits = g->pointer_size_bytes * 8;
213 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref);
214 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
221215 assert(child_type->di_type);
222216 entry->di_type = LLVMZigCreateDebugPointerType(g->dbuilder, child_type->di_type,
223 entry->size_in_bits, entry->align_in_bits, buf_ptr(&entry->name));
217 debug_size_in_bits, debug_align_in_bits, buf_ptr(&entry->name));
224218 }
225219
226220 entry->data.pointer.child_type = child_type;
......@@ -249,8 +243,6 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {
249243 // this is an optimization but also is necessary for calling C
250244 // functions where all pointers are maybe pointers
251245 // function types are technically pointers
252 entry->size_in_bits = child_type->size_in_bits;
253 entry->align_in_bits = child_type->align_in_bits;
254246 entry->type_ref = child_type->type_ref;
255247 entry->di_type = child_type->di_type;
256248 } else {
......@@ -260,8 +252,6 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {
260252 LLVMInt1Type(),
261253 };
262254 entry->type_ref = LLVMStructType(elem_types, 2, false);
263 entry->size_in_bits = child_type->size_in_bits + 8;
264 entry->align_in_bits = child_type->align_in_bits;
265255
266256
267257 LLVMZigDIScope *compile_unit_scope = LLVMZigCompileUnitToScope(g->compile_unit);
......@@ -271,18 +261,36 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {
271261 LLVMZigTag_DW_structure_type(), buf_ptr(&entry->name),
272262 compile_unit_scope, di_file, line);
273263
264 uint64_t val_debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, child_type->type_ref);
265 uint64_t val_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, child_type->type_ref);
266 uint64_t val_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 0);
267
268 TypeTableEntry *bool_type = g->builtin_types.entry_bool;
269 uint64_t maybe_debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, bool_type->type_ref);
270 uint64_t maybe_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, bool_type->type_ref);
271 uint64_t maybe_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 1);
272
273 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref);
274 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
275
274276 LLVMZigDIType *di_element_types[] = {
275277 LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type),
276 "val", di_file, line, child_type->size_in_bits, child_type->align_in_bits, 0, 0,
277 child_type->di_type),
278 "val", di_file, line,
279 val_debug_size_in_bits,
280 val_debug_align_in_bits,
281 val_offset_in_bits,
282 0, child_type->di_type),
278283 LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type),
279 "maybe", di_file, line, 8, 8, child_type->size_in_bits, 0,
280 child_type->di_type),
284 "maybe", di_file, line,
285 maybe_debug_size_in_bits,
286 maybe_debug_align_in_bits,
287 maybe_offset_in_bits,
288 0, child_type->di_type),
281289 };
282290 LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder,
283291 compile_unit_scope,
284292 buf_ptr(&entry->name),
285 di_file, line, entry->size_in_bits, entry->align_in_bits, 0,
293 di_file, line, debug_size_in_bits, debug_align_in_bits, 0,
286294 nullptr, di_element_types, 2, 0, nullptr, "");
287295
288296 LLVMZigReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type);
......@@ -309,10 +317,8 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
309317
310318 entry->data.error.child_type = child_type;
311319
312 if (child_type->size_in_bits == 0) {
320 if (!type_has_bits(child_type)) {
313321 entry->type_ref = g->err_tag_type->type_ref;
314 entry->size_in_bits = g->err_tag_type->size_in_bits;
315 entry->align_in_bits = g->err_tag_type->align_in_bits;
316322 entry->di_type = g->err_tag_type->di_type;
317323
318324 } else {
......@@ -321,8 +327,6 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
321327 child_type->type_ref,
322328 };
323329 entry->type_ref = LLVMStructType(elem_types, 2, false);
324 entry->size_in_bits = g->err_tag_type->size_in_bits + child_type->size_in_bits;
325 entry->align_in_bits = g->err_tag_type->align_in_bits;
326330
327331 LLVMZigDIScope *compile_unit_scope = LLVMZigCompileUnitToScope(g->compile_unit);
328332 LLVMZigDIFile *di_file = nullptr;
......@@ -331,19 +335,39 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
331335 LLVMZigTag_DW_structure_type(), buf_ptr(&entry->name),
332336 compile_unit_scope, di_file, line);
333337
338 uint64_t tag_debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, g->err_tag_type->type_ref);
339 uint64_t tag_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, g->err_tag_type->type_ref);
340 uint64_t tag_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 0);
341
342 uint64_t value_debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, child_type->type_ref);
343 uint64_t value_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, child_type->type_ref);
344 uint64_t value_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 1);
345
346 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref);
347 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
348
334349 LLVMZigDIType *di_element_types[] = {
335350 LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type),
336 "tag", di_file, line, g->err_tag_type->size_in_bits, g->err_tag_type->align_in_bits,
337 0, 0, child_type->di_type),
351 "tag", di_file, line,
352 tag_debug_size_in_bits,
353 tag_debug_align_in_bits,
354 tag_offset_in_bits,
355 0, child_type->di_type),
338356 LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type),
339 "value", di_file, line, child_type->size_in_bits, child_type->align_in_bits,
340 g->err_tag_type->size_in_bits, 0, child_type->di_type),
357 "value", di_file, line,
358 value_debug_size_in_bits,
359 value_debug_align_in_bits,
360 value_offset_in_bits,
361 0, child_type->di_type),
341362 };
342363
343364 LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder,
344365 compile_unit_scope,
345366 buf_ptr(&entry->name),
346 di_file, line, entry->size_in_bits, entry->align_in_bits, 0,
367 di_file, line,
368 debug_size_in_bits,
369 debug_align_in_bits,
370 0,
347371 nullptr, di_element_types, 2, 0, nullptr, "");
348372
349373 LLVMZigReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type);
......@@ -363,14 +387,16 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t
363387 } else {
364388 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray);
365389 entry->type_ref = LLVMArrayType(child_type->type_ref, array_size);
390 entry->zero_bits = (array_size == 0) || child_type->zero_bits;
391
366392 buf_resize(&entry->name, 0);
367393 buf_appendf(&entry->name, "[%" PRIu64 "]%s", array_size, buf_ptr(&child_type->name));
368394
369 entry->size_in_bits = child_type->size_in_bits * array_size;
370 entry->align_in_bits = child_type->align_in_bits;
395 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref);
396 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
371397
372 entry->di_type = LLVMZigCreateDebugArrayType(g->dbuilder, entry->size_in_bits,
373 entry->align_in_bits, child_type->di_type, array_size);
398 entry->di_type = LLVMZigCreateDebugArrayType(g->dbuilder, debug_size_in_bits,
399 debug_align_in_bits, child_type->di_type, array_size);
374400 entry->data.array.child_type = child_type;
375401 entry->data.array.len = array_size;
376402
......@@ -379,14 +405,12 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t
379405 }
380406}
381407
382static void unknown_size_array_type_common_init(CodeGen *g, TypeTableEntry *child_type,
408static void slice_type_common_init(CodeGen *g, TypeTableEntry *child_type,
383409 bool is_const, TypeTableEntry *entry)
384410{
385411 TypeTableEntry *pointer_type = get_pointer_to_type(g, child_type, is_const);
386412
387413 unsigned element_count = 2;
388 entry->size_in_bits = g->pointer_size_bytes * 2 * 8;
389 entry->align_in_bits = g->pointer_size_bytes * 8;
390414 entry->data.structure.is_packed = false;
391415 entry->data.structure.is_unknown_size_array = true;
392416 entry->data.structure.src_field_count = element_count;
......@@ -402,20 +426,20 @@ static void unknown_size_array_type_common_init(CodeGen *g, TypeTableEntry *chil
402426 entry->data.structure.fields[1].gen_index = 1;
403427}
404428
405static TypeTableEntry *get_unknown_size_array_type(CodeGen *g, TypeTableEntry *child_type, bool is_const) {
429static TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_const) {
406430 assert(child_type->id != TypeTableEntryIdInvalid);
407431 TypeTableEntry **parent_pointer = &child_type->unknown_size_array_parent[(is_const ? 1 : 0)];
408432
409433 if (*parent_pointer) {
410434 return *parent_pointer;
411435 } else if (is_const) {
412 TypeTableEntry *var_peer = get_unknown_size_array_type(g, child_type, false);
436 TypeTableEntry *var_peer = get_slice_type(g, child_type, false);
413437 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct);
414438
415439 buf_resize(&entry->name, 0);
416440 buf_appendf(&entry->name, "[]const %s", buf_ptr(&child_type->name));
417441
418 unknown_size_array_type_common_init(g, child_type, is_const, entry);
442 slice_type_common_init(g, child_type, is_const, entry);
419443
420444 entry->type_ref = var_peer->type_ref;
421445 entry->di_type = var_peer->di_type;
......@@ -439,15 +463,17 @@ static TypeTableEntry *get_unknown_size_array_type(CodeGen *g, TypeTableEntry *c
439463 };
440464 LLVMStructSetBody(entry->type_ref, element_types, element_count, false);
441465
442 unknown_size_array_type_common_init(g, child_type, is_const, entry);
466 slice_type_common_init(g, child_type, is_const, entry);
443467
444468 LLVMZigDIType *di_element_types[] = {
445469 pointer_type->di_type,
446470 g->builtin_types.entry_isize->di_type,
447471 };
448472 LLVMZigDIScope *compile_unit_scope = LLVMZigCompileUnitToScope(g->compile_unit);
473 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref);
474 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
449475 entry->di_type = LLVMZigCreateDebugStructType(g->dbuilder, compile_unit_scope,
450 buf_ptr(&entry->name), g->dummy_di_file, 0, entry->size_in_bits, entry->align_in_bits, 0,
476 buf_ptr(&entry->name), g->dummy_di_file, 0, debug_size_in_bits, debug_align_in_bits, 0,
451477 nullptr, di_element_types, element_count, 0, nullptr, "");
452478
453479 entry->data.structure.complete = true;
......@@ -462,11 +488,9 @@ TypeTableEntry *get_typedecl_type(CodeGen *g, const char *name, TypeTableEntry *
462488
463489 buf_init_from_str(&entry->name, name);
464490
465 entry->type_ref = child_type->type_ref;
466491 entry->type_ref = child_type->type_ref;
467492 entry->di_type = child_type->di_type;
468 entry->size_in_bits = child_type->size_in_bits;
469 entry->align_in_bits = child_type->align_in_bits;
493 entry->zero_bits = child_type->zero_bits;
470494
471495 entry->data.type_decl.child_type = child_type;
472496
......@@ -497,9 +521,6 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId fn_type_id) {
497521 fn_type->data.fn.calling_convention = LLVMFastCallConv;
498522 }
499523
500 fn_type->size_in_bits = g->pointer_size_bytes * 8;
501 fn_type->align_in_bits = g->pointer_size_bytes * 8;
502
503524 // populate the name of the type
504525 buf_resize(&fn_type->name, 0);
505526 const char *extern_str = fn_type_id.is_extern ? "extern " : "";
......@@ -542,7 +563,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId fn_type_id) {
542563 // after the gen_param_index += 1 because 0 is the return type
543564 param_di_types[gen_param_index] = gen_type->di_type;
544565 gen_return_type = g->builtin_types.entry_void;
545 } else if (fn_type_id.return_type->size_in_bits == 0) {
566 } else if (!type_has_bits(fn_type_id.return_type)) {
546567 gen_return_type = g->builtin_types.entry_void;
547568 } else {
548569 gen_return_type = fn_type_id.return_type;
......@@ -559,7 +580,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId fn_type_id) {
559580 gen_param_info->gen_index = -1;
560581
561582 assert(type_is_complete(type_entry));
562 if (type_entry->size_in_bits > 0) {
583 if (type_has_bits(type_entry)) {
563584 TypeTableEntry *gen_type;
564585 if (handle_is_ptr(type_entry)) {
565586 gen_type = get_pointer_to_type(g, type_entry, true);
......@@ -897,37 +918,43 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
897918 AstNode *field_node = decl_node->data.struct_decl.fields.at(i);
898919 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i];
899920 type_enum_field->name = &field_node->data.struct_field.name;
900 type_enum_field->type_entry = analyze_type_expr(g, import, import->block_context,
921 TypeTableEntry *field_type = analyze_type_expr(g, import, import->block_context,
901922 field_node->data.struct_field.type);
923 type_enum_field->type_entry = field_type;
902924 type_enum_field->value = i;
903925
926
904927 di_enumerators[i] = LLVMZigCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i);
905928
906 if (type_enum_field->type_entry->id == TypeTableEntryIdStruct) {
907 resolve_struct_type(g, import, type_enum_field->type_entry);
908 } else if (type_enum_field->type_entry->id == TypeTableEntryIdEnum) {
909 resolve_enum_type(g, import, type_enum_field->type_entry);
910 } else if (type_enum_field->type_entry->id == TypeTableEntryIdInvalid) {
929 if (field_type->id == TypeTableEntryIdStruct) {
930 resolve_struct_type(g, import, field_type);
931 } else if (field_type->id == TypeTableEntryIdEnum) {
932 resolve_enum_type(g, import, field_type);
933 } else if (field_type->id == TypeTableEntryIdInvalid) {
911934 enum_type->data.enumeration.is_invalid = true;
912935 continue;
913 } else if (type_enum_field->type_entry->id == TypeTableEntryIdVoid) {
936 } else if (!type_has_bits(field_type)) {
914937 continue;
915938 }
916939
940 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, field_type->type_ref);
941 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, field_type->type_ref);
942
917943 union_inner_di_types[gen_field_index] = LLVMZigCreateDebugMemberType(g->dbuilder,
918944 LLVMZigTypeToScope(enum_type->di_type), buf_ptr(type_enum_field->name),
919945 import->di_file, field_node->line + 1,
920 type_enum_field->type_entry->size_in_bits,
921 type_enum_field->type_entry->align_in_bits,
922 0, 0, type_enum_field->type_entry->di_type);
946 debug_size_in_bits,
947 debug_align_in_bits,
948 0,
949 0, field_type->di_type);
923950
924 biggest_align_in_bits = max(biggest_align_in_bits, type_enum_field->type_entry->align_in_bits);
951 biggest_align_in_bits = max(biggest_align_in_bits, debug_align_in_bits);
925952
926953 if (!biggest_union_member ||
927 type_enum_field->type_entry->size_in_bits > biggest_union_member->size_in_bits)
954 debug_size_in_bits > biggest_union_member_size_in_bits)
928955 {
929 biggest_union_member = type_enum_field->type_entry;
930 biggest_union_member_size_in_bits = biggest_union_member->size_in_bits;
956 biggest_union_member = field_type;
957 biggest_union_member_size_in_bits = debug_size_in_bits;
931958 }
932959
933960 gen_field_index += 1;
......@@ -941,8 +968,6 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
941968 enum_type->data.enumeration.gen_field_count = gen_field_index;
942969
943970 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
944 enum_type->align_in_bits = tag_type_entry->size_in_bits;
945 enum_type->size_in_bits = tag_type_entry->size_in_bits + biggest_union_member_size_in_bits;
946971 enum_type->data.enumeration.tag_type = tag_type_entry;
947972
948973 if (biggest_union_member) {
......@@ -958,30 +983,37 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
958983 LLVMStructSetBody(enum_type->type_ref, root_struct_element_types, 2, false);
959984
960985 // create debug type for tag
986 uint64_t tag_debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, tag_type_entry->type_ref);
987 uint64_t tag_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, tag_type_entry->type_ref);
961988 LLVMZigDIType *tag_di_type = LLVMZigCreateDebugEnumerationType(g->dbuilder,
962989 LLVMZigTypeToScope(enum_type->di_type), "AnonEnum", import->di_file, decl_node->line + 1,
963 tag_type_entry->size_in_bits, tag_type_entry->align_in_bits, di_enumerators, field_count,
990 tag_debug_size_in_bits, tag_debug_align_in_bits, di_enumerators, field_count,
964991 tag_type_entry->di_type, "");
965992
966993 // create debug type for union
967994 LLVMZigDIType *union_di_type = LLVMZigCreateDebugUnionType(g->dbuilder,
968995 LLVMZigTypeToScope(enum_type->di_type), "AnonUnion", import->di_file, decl_node->line + 1,
969 biggest_union_member->size_in_bits, biggest_align_in_bits, 0, union_inner_di_types,
996 biggest_union_member_size_in_bits, biggest_align_in_bits, 0, union_inner_di_types,
970997 gen_field_index, 0, "");
971998
972999 // create debug types for members of root struct
1000 uint64_t tag_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, enum_type->type_ref, 0);
9731001 LLVMZigDIType *tag_member_di_type = LLVMZigCreateDebugMemberType(g->dbuilder,
9741002 LLVMZigTypeToScope(enum_type->di_type), "tag_field",
9751003 import->di_file, decl_node->line + 1,
976 tag_type_entry->size_in_bits,
977 tag_type_entry->align_in_bits,
978 0, 0, tag_di_type);
1004 tag_debug_size_in_bits,
1005 tag_debug_align_in_bits,
1006 tag_offset_in_bits,
1007 0, tag_di_type);
1008
1009 uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, enum_type->type_ref, 1);
9791010 LLVMZigDIType *union_member_di_type = LLVMZigCreateDebugMemberType(g->dbuilder,
9801011 LLVMZigTypeToScope(enum_type->di_type), "union_field",
9811012 import->di_file, decl_node->line + 1,
982 biggest_union_member->size_in_bits,
1013 biggest_union_member_size_in_bits,
9831014 biggest_align_in_bits,
984 tag_type_entry->size_in_bits, 0, union_di_type);
1015 union_offset_in_bits,
1016 0, union_di_type);
9851017
9861018 // create debug type for root struct
9871019 LLVMZigDIType *di_root_members[] = {
......@@ -990,11 +1022,15 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
9901022 };
9911023
9921024
1025 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, enum_type->type_ref);
1026 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, enum_type->type_ref);
9931027 LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder,
9941028 LLVMZigFileToScope(import->di_file),
9951029 buf_ptr(&decl_node->data.struct_decl.name),
996 import->di_file, decl_node->line + 1, enum_type->size_in_bits, enum_type->align_in_bits, 0,
997 nullptr, di_root_members, 2, 0, nullptr, "");
1030 import->di_file, decl_node->line + 1,
1031 debug_size_in_bits,
1032 debug_align_in_bits,
1033 0, nullptr, di_root_members, 2, 0, nullptr, "");
9981034
9991035 LLVMZigReplaceTemporary(g->dbuilder, enum_type->di_type, replacement_di_type);
10001036 enum_type->di_type = replacement_di_type;
......@@ -1003,10 +1039,14 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
10031039 enum_type->type_ref = tag_type_entry->type_ref;
10041040
10051041 // create debug type for tag
1042 uint64_t tag_debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, tag_type_entry->type_ref);
1043 uint64_t tag_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, tag_type_entry->type_ref);
10061044 LLVMZigDIType *tag_di_type = LLVMZigCreateDebugEnumerationType(g->dbuilder,
10071045 LLVMZigFileToScope(import->di_file), buf_ptr(&decl_node->data.struct_decl.name),
10081046 import->di_file, decl_node->line + 1,
1009 tag_type_entry->size_in_bits, tag_type_entry->align_in_bits, di_enumerators, field_count,
1047 tag_debug_size_in_bits,
1048 tag_debug_align_in_bits,
1049 di_enumerators, field_count,
10101050 tag_type_entry->di_type, "");
10111051
10121052 LLVMZigReplaceTemporary(g->dbuilder, enum_type->di_type, tag_di_type);
......@@ -1025,6 +1065,7 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
10251065 AstNode *decl_node = struct_type->data.structure.decl_node;
10261066
10271067 if (struct_type->data.structure.embedded_in_current) {
1068 struct_type->data.structure.is_invalid = true;
10281069 if (!struct_type->data.structure.reported_infinite_err) {
10291070 struct_type->data.structure.reported_infinite_err = true;
10301071 add_node_error(g, decl_node,
......@@ -1049,11 +1090,6 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
10491090 // we possibly allocate too much here since gen_field_count can be lower than field_count.
10501091 // the only problem is potential wasted space though.
10511092 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);
1052 LLVMZigDIType **di_element_types = allocate<LLVMZigDIType*>(field_count);
1053
1054 uint64_t total_size_in_bits = 0;
1055 uint64_t first_field_align_in_bits = 0;
1056 uint64_t offset_in_bits = 0;
10571093
10581094 // this field should be set to true only during the recursive calls to resolve_struct_type
10591095 struct_type->data.structure.embedded_in_current = true;
......@@ -1063,41 +1099,28 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
10631099 AstNode *field_node = decl_node->data.struct_decl.fields.at(i);
10641100 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
10651101 type_struct_field->name = &field_node->data.struct_field.name;
1066 type_struct_field->type_entry = analyze_type_expr(g, import, import->block_context,
1102 TypeTableEntry *field_type = analyze_type_expr(g, import, import->block_context,
10671103 field_node->data.struct_field.type);
1104 type_struct_field->type_entry = field_type;
10681105 type_struct_field->src_index = i;
10691106 type_struct_field->gen_index = -1;
10701107
1071 if (type_struct_field->type_entry->id == TypeTableEntryIdStruct) {
1072 resolve_struct_type(g, import, type_struct_field->type_entry);
1073 } else if (type_struct_field->type_entry->id == TypeTableEntryIdEnum) {
1074 resolve_enum_type(g, import, type_struct_field->type_entry);
1075 } else if (type_struct_field->type_entry->id == TypeTableEntryIdInvalid) {
1108 if (field_type->id == TypeTableEntryIdStruct) {
1109 resolve_struct_type(g, import, field_type);
1110 } else if (field_type->id == TypeTableEntryIdEnum) {
1111 resolve_enum_type(g, import, field_type);
1112 } else if (field_type->id == TypeTableEntryIdInvalid) {
10761113 struct_type->data.structure.is_invalid = true;
10771114 continue;
1078 } else if (type_struct_field->type_entry->id == TypeTableEntryIdVoid) {
1115 } else if (!type_has_bits(field_type)) {
10791116 continue;
10801117 }
10811118
10821119 type_struct_field->gen_index = gen_field_index;
10831120
1084 di_element_types[gen_field_index] = LLVMZigCreateDebugMemberType(g->dbuilder,
1085 LLVMZigTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name),
1086 import->di_file, field_node->line + 1,
1087 type_struct_field->type_entry->size_in_bits,
1088 type_struct_field->type_entry->align_in_bits,
1089 offset_in_bits, 0, type_struct_field->type_entry->di_type);
1090
1091 element_types[gen_field_index] = type_struct_field->type_entry->type_ref;
1092 assert(di_element_types[gen_field_index]);
1121 element_types[gen_field_index] = field_type->type_ref;
10931122 assert(element_types[gen_field_index]);
10941123
1095 total_size_in_bits += type_struct_field->type_entry->size_in_bits;
1096 if (first_field_align_in_bits == 0) {
1097 first_field_align_in_bits = type_struct_field->type_entry->align_in_bits;
1098 }
1099 offset_in_bits += type_struct_field->type_entry->size_in_bits;
1100
11011124 gen_field_index += 1;
11021125 }
11031126 struct_type->data.structure.embedded_in_current = false;
......@@ -1105,22 +1128,55 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
11051128 struct_type->data.structure.gen_field_count = gen_field_index;
11061129 struct_type->data.structure.complete = true;
11071130
1108 if (!struct_type->data.structure.is_invalid) {
1131 if (struct_type->data.structure.is_invalid) {
1132 return;
1133 }
11091134
1110 LLVMStructSetBody(struct_type->type_ref, element_types, gen_field_index, false);
1135 int gen_field_count = gen_field_index;
1136 LLVMStructSetBody(struct_type->type_ref, element_types, gen_field_count, false);
11111137
1112 struct_type->align_in_bits = first_field_align_in_bits;
1113 struct_type->size_in_bits = total_size_in_bits;
1138 LLVMZigDIType **di_element_types = allocate<LLVMZigDIType*>(gen_field_count);
11141139
1115 LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder,
1116 LLVMZigFileToScope(import->di_file),
1117 buf_ptr(&decl_node->data.struct_decl.name),
1118 import->di_file, decl_node->line + 1, struct_type->size_in_bits, struct_type->align_in_bits, 0,
1119 nullptr, di_element_types, gen_field_index, 0, nullptr, "");
1140 for (int i = 0; i < field_count; i += 1) {
1141 AstNode *field_node = decl_node->data.struct_decl.fields.at(i);
1142 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
1143 gen_field_index = type_struct_field->gen_index;
1144 if (gen_field_index == -1) {
1145 continue;
1146 }
1147
1148 TypeTableEntry *field_type = type_struct_field->type_entry;
1149
1150 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, field_type->type_ref);
1151 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, field_type->type_ref);
1152 uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref,
1153 gen_field_index);
1154 di_element_types[gen_field_index] = LLVMZigCreateDebugMemberType(g->dbuilder,
1155 LLVMZigTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name),
1156 import->di_file, field_node->line + 1,
1157 debug_size_in_bits,
1158 debug_align_in_bits,
1159 debug_offset_in_bits,
1160 0, field_type->di_type);
11201161
1121 LLVMZigReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type);
1122 struct_type->di_type = replacement_di_type;
1162 assert(di_element_types[gen_field_index]);
11231163 }
1164
1165
1166 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, struct_type->type_ref);
1167 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, struct_type->type_ref);
1168 LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder,
1169 LLVMZigFileToScope(import->di_file),
1170 buf_ptr(&decl_node->data.struct_decl.name),
1171 import->di_file, decl_node->line + 1,
1172 debug_size_in_bits,
1173 debug_align_in_bits,
1174 0, nullptr, di_element_types, gen_field_count, 0, nullptr, "");
1175
1176 LLVMZigReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type);
1177 struct_type->di_type = replacement_di_type;
1178
1179 struct_type->zero_bits = (debug_size_in_bits == 0);
11241180}
11251181
11261182static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,
......@@ -1498,7 +1554,7 @@ static void add_global_const_expr(CodeGen *g, Expr *expr) {
14981554 if (expr->const_val.ok &&
14991555 type_has_codegen_value(expr->type_entry) &&
15001556 !expr->has_global_const &&
1501 expr->type_entry->size_in_bits > 0)
1557 type_has_bits(expr->type_entry))
15021558 {
15031559 g->global_const_list.append(expr);
15041560 expr->has_global_const = true;
......@@ -1517,7 +1573,7 @@ static bool num_lit_fits_in_other_type(CodeGen *g, AstNode *literal_node, TypeTa
15171573 } else if (other_type->id == TypeTableEntryIdInt &&
15181574 const_val->data.x_bignum.kind == BigNumKindInt)
15191575 {
1520 if (bignum_fits_in_bits(&const_val->data.x_bignum, other_type->size_in_bits,
1576 if (bignum_fits_in_bits(&const_val->data.x_bignum, other_type->data.integral.bit_count,
15211577 other_type->data.integral.is_signed))
15221578 {
15231579 return true;
......@@ -1653,14 +1709,14 @@ static TypeTableEntry *determine_peer_type_compatibility(CodeGen *g, AstNode *pa
16531709 cur_type->id == TypeTableEntryIdInt &&
16541710 prev_type->data.integral.is_signed == cur_type->data.integral.is_signed)
16551711 {
1656 if (cur_type->size_in_bits > prev_type->size_in_bits) {
1712 if (cur_type->data.integral.bit_count > prev_type->data.integral.bit_count) {
16571713 prev_type = cur_type;
16581714 prev_node = cur_node;
16591715 }
16601716 } else if (prev_type->id == TypeTableEntryIdFloat &&
16611717 cur_type->id == TypeTableEntryIdFloat)
16621718 {
1663 if (cur_type->size_in_bits > prev_type->size_in_bits) {
1719 if (cur_type->data.floating.bit_count > prev_type->data.floating.bit_count) {
16641720 prev_type = cur_type;
16651721 prev_node = cur_node;
16661722 }
......@@ -1737,7 +1793,7 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_
17371793 if (expected_type->id == TypeTableEntryIdInt &&
17381794 actual_type->id == TypeTableEntryIdInt &&
17391795 expected_type->data.integral.is_signed == actual_type->data.integral.is_signed &&
1740 expected_type->size_in_bits >= actual_type->size_in_bits)
1796 expected_type->data.integral.bit_count >= actual_type->data.integral.bit_count)
17411797 {
17421798 return true;
17431799 }
......@@ -1745,7 +1801,7 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_
17451801 // implicit float widening conversion
17461802 if (expected_type->id == TypeTableEntryIdFloat &&
17471803 actual_type->id == TypeTableEntryIdFloat &&
1748 expected_type->size_in_bits >= actual_type->size_in_bits)
1804 expected_type->data.floating.bit_count >= actual_type->data.floating.bit_count)
17491805 {
17501806 return true;
17511807 }
......@@ -2221,15 +2277,15 @@ static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import,
22212277 if (array_type->id == TypeTableEntryIdInvalid) {
22222278 return_type = g->builtin_types.entry_invalid;
22232279 } else if (array_type->id == TypeTableEntryIdArray) {
2224 return_type = get_unknown_size_array_type(g, array_type->data.array.child_type,
2280 return_type = get_slice_type(g, array_type->data.array.child_type,
22252281 node->data.slice_expr.is_const);
22262282 } else if (array_type->id == TypeTableEntryIdPointer) {
2227 return_type = get_unknown_size_array_type(g, array_type->data.pointer.child_type,
2283 return_type = get_slice_type(g, array_type->data.pointer.child_type,
22282284 node->data.slice_expr.is_const);
22292285 } else if (array_type->id == TypeTableEntryIdStruct &&
22302286 array_type->data.structure.is_unknown_size_array)
22312287 {
2232 return_type = get_unknown_size_array_type(g,
2288 return_type = get_slice_type(g,
22332289 array_type->data.structure.fields[0].type_entry->data.pointer.child_type,
22342290 node->data.slice_expr.is_const);
22352291 } else {
......@@ -2666,7 +2722,7 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im
26662722 bool are_equal = false;
26672723 if (enum1->tag == enum2->tag) {
26682724 TypeEnumField *enum_field = &op1_type->data.enumeration.fields[enum1->tag];
2669 if (enum_field->type_entry->size_in_bits > 0) {
2725 if (type_has_bits(enum_field->type_entry)) {
26702726 zig_panic("TODO const expr analyze enum special value for equality");
26712727 } else {
26722728 are_equal = true;
......@@ -2839,7 +2895,7 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import,
28392895 AstNode **op1 = node->data.bin_op_expr.op1->parent_field;
28402896 AstNode **op2 = node->data.bin_op_expr.op2->parent_field;
28412897
2842 TypeTableEntry *str_type = get_unknown_size_array_type(g, g->builtin_types.entry_u8, true);
2898 TypeTableEntry *str_type = get_slice_type(g, g->builtin_types.entry_u8, true);
28432899
28442900 TypeTableEntry *op1_type = analyze_expression(g, import, context, str_type, *op1);
28452901 TypeTableEntry *op2_type = analyze_expression(g, import, context, str_type, *op2);
......@@ -3162,11 +3218,11 @@ static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import,
31623218 }
31633219 } else {
31643220 return resolve_expr_const_val_as_type(g, node,
3165 get_unknown_size_array_type(g, child_type, node->data.array_type.is_const));
3221 get_slice_type(g, child_type, node->data.array_type.is_const));
31663222 }
31673223 } else {
31683224 return resolve_expr_const_val_as_type(g, node,
3169 get_unknown_size_array_type(g, child_type, node->data.array_type.is_const));
3225 get_slice_type(g, child_type, node->data.array_type.is_const));
31703226 }
31713227}
31723228
......@@ -3357,13 +3413,13 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor
33573413 if (is_max) {
33583414 if (type_entry->data.integral.is_signed) {
33593415 int64_t val;
3360 if (type_entry->size_in_bits == 64) {
3416 if (type_entry->data.integral.bit_count == 64) {
33613417 val = INT64_MAX;
3362 } else if (type_entry->size_in_bits == 32) {
3418 } else if (type_entry->data.integral.bit_count == 32) {
33633419 val = INT32_MAX;
3364 } else if (type_entry->size_in_bits == 16) {
3420 } else if (type_entry->data.integral.bit_count == 16) {
33653421 val = INT16_MAX;
3366 } else if (type_entry->size_in_bits == 8) {
3422 } else if (type_entry->data.integral.bit_count == 8) {
33673423 val = INT8_MAX;
33683424 } else {
33693425 zig_unreachable();
......@@ -3371,13 +3427,13 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor
33713427 bignum_init_signed(&const_val->data.x_bignum, val);
33723428 } else {
33733429 uint64_t val;
3374 if (type_entry->size_in_bits == 64) {
3430 if (type_entry->data.integral.bit_count == 64) {
33753431 val = UINT64_MAX;
3376 } else if (type_entry->size_in_bits == 32) {
3432 } else if (type_entry->data.integral.bit_count == 32) {
33773433 val = UINT32_MAX;
3378 } else if (type_entry->size_in_bits == 16) {
3434 } else if (type_entry->data.integral.bit_count == 16) {
33793435 val = UINT16_MAX;
3380 } else if (type_entry->size_in_bits == 8) {
3436 } else if (type_entry->data.integral.bit_count == 8) {
33813437 val = UINT8_MAX;
33823438 } else {
33833439 zig_unreachable();
......@@ -3387,13 +3443,13 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor
33873443 } else {
33883444 if (type_entry->data.integral.is_signed) {
33893445 int64_t val;
3390 if (type_entry->size_in_bits == 64) {
3446 if (type_entry->data.integral.bit_count == 64) {
33913447 val = INT64_MIN;
3392 } else if (type_entry->size_in_bits == 32) {
3448 } else if (type_entry->data.integral.bit_count == 32) {
33933449 val = INT32_MIN;
3394 } else if (type_entry->size_in_bits == 16) {
3450 } else if (type_entry->data.integral.bit_count == 16) {
33953451 val = INT16_MIN;
3396 } else if (type_entry->size_in_bits == 8) {
3452 } else if (type_entry->data.integral.bit_count == 8) {
33973453 val = INT8_MIN;
33983454 } else {
33993455 zig_unreachable();
......@@ -3657,14 +3713,16 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
36573713
36583714 // explicit cast from %void to integer type which can fit it
36593715 bool actual_type_is_void_err = actual_type->id == TypeTableEntryIdErrorUnion &&
3660 actual_type->data.error.child_type->size_in_bits == 0;
3716 !type_has_bits(actual_type->data.error.child_type);
36613717 bool actual_type_is_pure_err = actual_type->id == TypeTableEntryIdPureError;
36623718 if ((actual_type_is_void_err || actual_type_is_pure_err) &&
36633719 wanted_type->id == TypeTableEntryIdInt)
36643720 {
36653721 BigNum bn;
36663722 bignum_init_unsigned(&bn, g->error_value_count);
3667 if (bignum_fits_in_bits(&bn, wanted_type->size_in_bits, wanted_type->data.integral.is_signed)) {
3723 if (bignum_fits_in_bits(&bn, wanted_type->data.integral.bit_count,
3724 wanted_type->data.integral.is_signed))
3725 {
36683726 node->data.fn_call_expr.cast_op = CastOpErrToInt;
36693727 eval_const_expr_implicit_cast(g, node, expr_node);
36703728 return wanted_type;
......@@ -3767,13 +3825,13 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
37673825 if (dest_type->id == TypeTableEntryIdPointer &&
37683826 src_type->id == TypeTableEntryIdPointer)
37693827 {
3770 uint64_t dest_align_bits = dest_type->data.pointer.child_type->align_in_bits;
3771 uint64_t src_align_bits = src_type->data.pointer.child_type->align_in_bits;
3772 if (dest_align_bits != src_align_bits) {
3828 uint64_t dest_align = get_memcpy_align(g, dest_type->data.pointer.child_type);
3829 uint64_t src_align = get_memcpy_align(g, src_type->data.pointer.child_type);
3830 if (dest_align != src_align) {
37733831 add_node_error(g, dest_node, buf_sprintf(
37743832 "misaligned memcpy, '%s' has alignment '%" PRIu64 ", '%s' has alignment %" PRIu64,
3775 buf_ptr(&dest_type->name), dest_align_bits / 8,
3776 buf_ptr(&src_type->name), src_align_bits / 8));
3833 buf_ptr(&dest_type->name), dest_align,
3834 buf_ptr(&src_type->name), src_align));
37773835 }
37783836 }
37793837
......@@ -3808,10 +3866,30 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
38083866 buf_sprintf("no size available for type '%s'", buf_ptr(&type_entry->name)));
38093867 return g->builtin_types.entry_invalid;
38103868 } else {
3811 uint64_t size_in_bytes = type_entry->size_in_bits / 8;
3869 uint64_t size_in_bytes;
3870 if (type_has_bits(type_entry)) {
3871 size_in_bytes = LLVMStoreSizeOfType(g->target_data_ref, type_entry->type_ref);
3872 } else {
3873 size_in_bytes = 0;
3874 }
38123875 return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type, size_in_bytes);
38133876 }
38143877 }
3878 case BuiltinFnIdAlignof:
3879 {
3880 AstNode *type_node = node->data.fn_call_expr.params.at(0);
3881 TypeTableEntry *type_entry = analyze_type_expr(g, import, context, type_node);
3882 if (type_entry->id == TypeTableEntryIdInvalid) {
3883 return g->builtin_types.entry_invalid;
3884 } else if (type_entry->id == TypeTableEntryIdUnreachable) {
3885 add_node_error(g, first_executing_node(type_node),
3886 buf_sprintf("no align available for type '%s'", buf_ptr(&type_entry->name)));
3887 return g->builtin_types.entry_invalid;
3888 } else {
3889 uint64_t align_in_bytes = LLVMABISizeOfType(g->target_data_ref, type_entry->type_ref);
3890 return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type, align_in_bytes);
3891 }
3892 }
38153893 case BuiltinFnIdMaxValue:
38163894 return analyze_min_max_value(g, import, context, node,
38173895 "no max value available for type '%s'", true);
......@@ -3874,7 +3952,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
38743952 }
38753953
38763954 AstNode **str_node = node->data.fn_call_expr.params.at(0)->parent_field;
3877 TypeTableEntry *str_type = get_unknown_size_array_type(g, g->builtin_types.entry_u8, true);
3955 TypeTableEntry *str_type = get_slice_type(g, g->builtin_types.entry_u8, true);
38783956 TypeTableEntry *resolved_type = analyze_expression(g, import, context, str_type, *str_node);
38793957
38803958 if (resolved_type->id == TypeTableEntryIdInvalid) {
......@@ -3911,7 +3989,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
39113989 {
39123990 AstNode **str_node = node->data.fn_call_expr.params.at(0)->parent_field;
39133991
3914 TypeTableEntry *str_type = get_unknown_size_array_type(g, g->builtin_types.entry_u8, true);
3992 TypeTableEntry *str_type = get_slice_type(g, g->builtin_types.entry_u8, true);
39153993 TypeTableEntry *resolved_type = analyze_expression(g, import, context, str_type, *str_node);
39163994
39173995 if (resolved_type->id == TypeTableEntryIdInvalid) {
......@@ -5317,8 +5395,6 @@ void semantic_analyze(CodeGen *g) {
53175395 g->err_tag_type = get_smallest_unsigned_int_type(g, g->error_value_count);
53185396
53195397 g->builtin_types.entry_pure_error->type_ref = g->err_tag_type->type_ref;
5320 g->builtin_types.entry_pure_error->size_in_bits = g->err_tag_type->size_in_bits;
5321 g->builtin_types.entry_pure_error->align_in_bits = g->err_tag_type->align_in_bits;
53225398 g->builtin_types.entry_pure_error->di_type = g->err_tag_type->di_type;
53235399 }
53245400
......@@ -5571,7 +5647,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
55715647 case TypeTableEntryIdStruct:
55725648 return true;
55735649 case TypeTableEntryIdErrorUnion:
5574 return type_entry->data.error.child_type->size_in_bits > 0;
5650 return type_has_bits(type_entry->data.error.child_type);
55755651 case TypeTableEntryIdEnum:
55765652 return type_entry->data.enumeration.gen_field_count != 0;
55775653 case TypeTableEntryIdMaybe:
......@@ -5640,3 +5716,59 @@ bool fn_type_id_eql(FnTypeId a, FnTypeId b) {
56405716 }
56415717 return true;
56425718}
5719
5720bool type_has_bits(TypeTableEntry *type_entry) {
5721 assert(type_entry);
5722 assert(type_entry->id != TypeTableEntryIdInvalid);
5723 return !type_entry->zero_bits;
5724}
5725
5726static TypeTableEntry *first_struct_field_type(TypeTableEntry *type_entry) {
5727 assert(type_entry->id == TypeTableEntryIdStruct);
5728 for (int i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
5729 TypeStructField *tsf = &type_entry->data.structure.fields[i];
5730 if (tsf->gen_index == 0) {
5731 return tsf->type_entry;
5732 }
5733 }
5734 zig_unreachable();
5735}
5736
5737static TypeTableEntry *type_of_first_thing_in_memory(TypeTableEntry *type_entry) {
5738 assert(type_has_bits(type_entry));
5739 switch (type_entry->id) {
5740 case TypeTableEntryIdInvalid:
5741 case TypeTableEntryIdNumLitFloat:
5742 case TypeTableEntryIdNumLitInt:
5743 case TypeTableEntryIdUndefLit:
5744 case TypeTableEntryIdUnreachable:
5745 case TypeTableEntryIdMetaType:
5746 case TypeTableEntryIdVoid:
5747 zig_unreachable();
5748 case TypeTableEntryIdArray:
5749 return type_of_first_thing_in_memory(type_entry->data.array.child_type);
5750 case TypeTableEntryIdStruct:
5751 return type_of_first_thing_in_memory(first_struct_field_type(type_entry));
5752 case TypeTableEntryIdMaybe:
5753 return type_of_first_thing_in_memory(type_entry->data.maybe.child_type);
5754 case TypeTableEntryIdErrorUnion:
5755 return type_of_first_thing_in_memory(type_entry->data.error.child_type);
5756 case TypeTableEntryIdTypeDecl:
5757 return type_of_first_thing_in_memory(type_entry->data.type_decl.canonical_type);
5758 case TypeTableEntryIdEnum:
5759 return type_entry->data.enumeration.tag_type;
5760 case TypeTableEntryIdPureError:
5761 case TypeTableEntryIdFn:
5762 case TypeTableEntryIdBool:
5763 case TypeTableEntryIdInt:
5764 case TypeTableEntryIdFloat:
5765 case TypeTableEntryIdPointer:
5766 return type_entry;
5767 }
5768}
5769
5770uint64_t get_memcpy_align(CodeGen *g, TypeTableEntry *type_entry) {
5771 TypeTableEntry *first_type_in_mem = type_of_first_thing_in_memory(type_entry);
5772 return LLVMABISizeOfType(g->target_data_ref, first_type_in_mem->type_ref);
5773}
5774
src/analyze.hpp+2
......@@ -35,5 +35,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry);
3535void find_libc_path(CodeGen *g);
3636
3737TypeTableEntry *get_underlying_type(TypeTableEntry *type_entry);
38bool type_has_bits(TypeTableEntry *type_entry);
39uint64_t get_memcpy_align(CodeGen *g, TypeTableEntry *type_entry);
3840
3941#endif
src/codegen.cpp+106-62
......@@ -145,8 +145,9 @@ static int bits_index(int size_in_bits) {
145145static LLVMValueRef get_arithmetic_overflow_fn(CodeGen *g, TypeTableEntry *type_entry,
146146 const char *signed_name, const char *unsigned_name)
147147{
148 assert(type_entry->id == TypeTableEntryIdInt);
148149 const char *signed_str = type_entry->data.integral.is_signed ? signed_name : unsigned_name;
149 Buf *llvm_name = buf_sprintf("llvm.%s.with.overflow.i%" PRIu64, signed_str, type_entry->size_in_bits);
150 Buf *llvm_name = buf_sprintf("llvm.%s.with.overflow.i%d", signed_str, type_entry->data.integral.bit_count);
150151
151152 LLVMTypeRef return_elem_types[] = {
152153 type_entry->type_ref,
......@@ -168,7 +169,7 @@ static LLVMValueRef get_int_overflow_fn(CodeGen *g, TypeTableEntry *type_entry,
168169 // [0-signed,1-unsigned][0-add,1-sub,2-mul][0-8,1-16,2-32,3-64]
169170 int index0 = type_entry->data.integral.is_signed ? 0 : 1;
170171 int index1 = add_sub_mul;
171 int index2 = bits_index(type_entry->size_in_bits);
172 int index2 = bits_index(type_entry->data.integral.bit_count);
172173 LLVMValueRef *fn = &g->int_overflow_fns[index0][index1][index2];
173174 if (*fn) {
174175 return *fn;
......@@ -188,7 +189,6 @@ static LLVMValueRef get_int_overflow_fn(CodeGen *g, TypeTableEntry *type_entry,
188189 return *fn;
189190}
190191
191
192192static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
193193 assert(node->type == NodeTypeFnCallExpr);
194194 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
......@@ -257,7 +257,7 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
257257 LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, "");
258258 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr, ptr_u8, "");
259259
260 uint64_t align_in_bytes = dest_type->data.pointer.child_type->align_in_bits / 8;
260 uint64_t align_in_bytes = get_memcpy_align(g, dest_type->data.pointer.child_type);
261261
262262 LLVMValueRef params[] = {
263263 dest_ptr_casted, // dest pointer
......@@ -287,7 +287,7 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
287287 add_debug_source_node(g, node);
288288 LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, "");
289289
290 uint64_t align_in_bytes = dest_type->data.pointer.child_type->align_in_bits / 8;
290 uint64_t align_in_bytes = get_memcpy_align(g, dest_type->data.pointer.child_type);
291291
292292 LLVMValueRef params[] = {
293293 dest_ptr_casted, // dest pointer
......@@ -301,6 +301,7 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
301301 return nullptr;
302302 }
303303 case BuiltinFnIdSizeof:
304 case BuiltinFnIdAlignof:
304305 case BuiltinFnIdMinValue:
305306 case BuiltinFnIdMaxValue:
306307 case BuiltinFnIdMemberCount:
......@@ -359,9 +360,21 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT
359360 TypeTableEntry *wanted_type, LLVMValueRef expr_val)
360361{
361362 assert(actual_type->id == wanted_type->id);
362 if (actual_type->size_in_bits == wanted_type->size_in_bits) {
363 uint64_t actual_bits;
364 uint64_t wanted_bits;
365 if (actual_type->id == TypeTableEntryIdFloat) {
366 actual_bits = actual_type->data.floating.bit_count;
367 wanted_bits = wanted_type->data.floating.bit_count;
368 } else if (actual_type->id == TypeTableEntryIdInt) {
369 actual_bits = actual_type->data.integral.bit_count;
370 wanted_bits = wanted_type->data.integral.bit_count;
371 } else {
372 zig_unreachable();
373 }
374
375 if (actual_bits == wanted_bits) {
363376 return expr_val;
364 } else if (actual_type->size_in_bits < wanted_type->size_in_bits) {
377 } else if (actual_bits < wanted_bits) {
365378 if (actual_type->id == TypeTableEntryIdFloat) {
366379 add_debug_source_node(g, source_node);
367380 return LLVMBuildFPExt(g->builder, expr_val, wanted_type->type_ref, "");
......@@ -376,7 +389,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT
376389 } else {
377390 zig_unreachable();
378391 }
379 } else if (actual_type->size_in_bits > wanted_type->size_in_bits) {
392 } else if (actual_bits > wanted_bits) {
380393 if (actual_type->id == TypeTableEntryIdFloat) {
381394 add_debug_source_node(g, source_node);
382395 return LLVMBuildFPTrunc(g->builder, expr_val, wanted_type->type_ref, "");
......@@ -410,7 +423,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
410423 return expr_val;
411424 case CastOpErrToInt:
412425 assert(actual_type->id == TypeTableEntryIdErrorUnion);
413 if (actual_type->data.error.child_type->size_in_bits == 0) {
426 if (!type_has_bits(actual_type->data.error.child_type)) {
414427 return gen_widen_or_shorten(g, node, g->err_tag_type, wanted_type, expr_val);
415428 } else {
416429 zig_panic("TODO");
......@@ -446,7 +459,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
446459 TypeTableEntry *child_type = wanted_type->data.error.child_type;
447460 LLVMValueRef ok_err_val = LLVMConstNull(g->err_tag_type->type_ref);
448461
449 if (child_type->size_in_bits == 0) {
462 if (!type_has_bits(child_type)) {
450463 return ok_err_val;
451464 } else {
452465 assert(cast_expr->tmp_ptr);
......@@ -466,7 +479,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
466479 }
467480 case CastOpPureErrorWrap:
468481 assert(wanted_type->id == TypeTableEntryIdErrorUnion);
469 if (wanted_type->data.error.child_type->size_in_bits == 0) {
482 if (!type_has_bits(wanted_type->data.error.child_type)) {
470483 return expr_val;
471484 } else {
472485 zig_panic("TODO");
......@@ -607,7 +620,7 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {
607620 AstNode *expr_node = node->data.fn_call_expr.params.at(i);
608621 LLVMValueRef param_value = gen_expr(g, expr_node);
609622 TypeTableEntry *param_type = get_expr_type(expr_node);
610 if (is_var_args || param_type->size_in_bits > 0) {
623 if (is_var_args || type_has_bits(param_type)) {
611624 gen_param_values[gen_param_index] = param_value;
612625 gen_param_index += 1;
613626 }
......@@ -621,7 +634,7 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {
621634 return LLVMBuildUnreachable(g->builder);
622635 } else if (first_arg_ret) {
623636 return node->data.fn_call_expr.tmp_ptr;
624 } else if (src_return_type->size_in_bits == 0) {
637 } else if (!type_has_bits(src_return_type)) {
625638 return nullptr;
626639 } else {
627640 return result;
......@@ -653,7 +666,7 @@ static LLVMValueRef gen_array_elem_ptr(CodeGen *g, AstNode *source_node, LLVMVal
653666{
654667 assert(subscript_value);
655668
656 if (array_type->size_in_bits == 0) {
669 if (!type_has_bits(array_type)) {
657670 return nullptr;
658671 }
659672
......@@ -978,7 +991,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
978991 case PrefixOpDereference:
979992 {
980993 LLVMValueRef expr = gen_expr(g, expr_node);
981 if (expr_type->size_in_bits == 0) {
994 if (!type_has_bits(expr_type)) {
982995 return nullptr;
983996 } else {
984997 add_debug_source_node(g, node);
......@@ -1002,7 +1015,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
10021015
10031016 if (g->build_type != CodeGenBuildTypeRelease) {
10041017 LLVMValueRef err_val;
1005 if (child_type->size_in_bits > 0) {
1018 if (type_has_bits(child_type)) {
10061019 add_debug_source_node(g, node);
10071020 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 0, "");
10081021 err_val = LLVMBuildLoad(g->builder, err_val_ptr, "");
......@@ -1022,7 +1035,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
10221035 LLVMPositionBuilderAtEnd(g->builder, ok_block);
10231036 }
10241037
1025 if (child_type->size_in_bits > 0) {
1038 if (type_has_bits(child_type)) {
10261039 LLVMValueRef child_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, "");
10271040 if (handle_is_ptr(child_type)) {
10281041 return child_val_ptr;
......@@ -1337,11 +1350,15 @@ static LLVMValueRef gen_struct_memcpy(CodeGen *g, AstNode *source_node, LLVMValu
13371350 LLVMValueRef src_ptr = LLVMBuildBitCast(g->builder, src, ptr_u8, "");
13381351 LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, dest, ptr_u8, "");
13391352
1353 TypeTableEntry *isize = g->builtin_types.entry_isize;
1354 uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, type_entry->type_ref);
1355 uint64_t align_bytes = get_memcpy_align(g, type_entry);
1356
13401357 LLVMValueRef params[] = {
13411358 dest_ptr, // dest pointer
13421359 src_ptr, // source pointer
1343 LLVMConstInt(LLVMIntType(g->pointer_size_bytes * 8), type_entry->size_in_bits / 8, false), // byte count
1344 LLVMConstInt(LLVMInt32Type(), type_entry->align_in_bits / 8, false), // align in bytes
1360 LLVMConstInt(isize->type_ref, size_bytes, false),
1361 LLVMConstInt(LLVMInt32Type(), align_bytes, false),
13451362 LLVMConstNull(LLVMInt1Type()), // is volatile
13461363 };
13471364
......@@ -1384,7 +1401,7 @@ static LLVMValueRef gen_assign_expr(CodeGen *g, AstNode *node) {
13841401
13851402 LLVMValueRef value = gen_expr(g, node->data.bin_op_expr.op2);
13861403
1387 if (op1_type->size_in_bits == 0) {
1404 if (!type_has_bits(op1_type)) {
13881405 return nullptr;
13891406 }
13901407
......@@ -1546,7 +1563,7 @@ static LLVMValueRef gen_unwrap_err_expr(CodeGen *g, AstNode *node) {
15461563 LLVMBasicBlockRef err_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapErrError");
15471564 LLVMBasicBlockRef end_block;
15481565 bool err_reachable = op2_type->id != TypeTableEntryIdUnreachable;
1549 bool have_end_block = err_reachable && (child_type->size_in_bits > 0);
1566 bool have_end_block = err_reachable && type_has_bits(child_type);
15501567 if (have_end_block) {
15511568 end_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapErrEnd");
15521569 }
......@@ -1566,7 +1583,7 @@ static LLVMValueRef gen_unwrap_err_expr(CodeGen *g, AstNode *node) {
15661583 }
15671584
15681585 LLVMPositionBuilderAtEnd(g->builder, ok_block);
1569 if (child_type->size_in_bits == 0) {
1586 if (!type_has_bits(child_type)) {
15701587 return nullptr;
15711588 }
15721589 LLVMValueRef child_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, "");
......@@ -1624,7 +1641,7 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) {
16241641
16251642 add_debug_source_node(g, node);
16261643 LLVMValueRef err_val;
1627 if (child_type->size_in_bits > 0) {
1644 if (type_has_bits(child_type)) {
16281645 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, value, 0, "");
16291646 err_val = LLVMBuildLoad(g->builder, err_val_ptr, "");
16301647 } else {
......@@ -1639,7 +1656,7 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) {
16391656 if (return_type->id == TypeTableEntryIdPureError) {
16401657 gen_return(g, node, err_val);
16411658 } else if (return_type->id == TypeTableEntryIdErrorUnion) {
1642 if (return_type->data.error.child_type->size_in_bits > 0) {
1659 if (type_has_bits(return_type->data.error.child_type)) {
16431660 assert(g->cur_ret_ptr);
16441661
16451662 add_debug_source_node(g, node);
......@@ -1654,7 +1671,7 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) {
16541671 }
16551672
16561673 LLVMPositionBuilderAtEnd(g->builder, continue_block);
1657 if (child_type->size_in_bits > 0) {
1674 if (type_has_bits(child_type)) {
16581675 add_debug_source_node(g, node);
16591676 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, value, 1, "");
16601677 if (handle_is_ptr(child_type)) {
......@@ -2164,7 +2181,7 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa
21642181 *init_value = gen_expr(g, var_decl->expr);
21652182 *expr_type = get_expr_type(var_decl->expr);
21662183 }
2167 if (variable->type->size_in_bits == 0) {
2184 if (!type_has_bits(variable->type)) {
21682185 return nullptr;
21692186 }
21702187
......@@ -2225,15 +2242,17 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa
22252242 }
22262243 }
22272244 if (!ignore_uninit && g->build_type != CodeGenBuildTypeRelease) {
2245 TypeTableEntry *isize = g->builtin_types.entry_isize;
2246 uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, variable->type->type_ref);
2247 uint64_t align_bytes = get_memcpy_align(g, variable->type);
2248
22282249 // memset uninitialized memory to 0xa
22292250 add_debug_source_node(g, source_node);
22302251 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
22312252 LLVMValueRef fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false);
22322253 LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, variable->value_ref, ptr_u8, "");
2233 LLVMValueRef byte_count = LLVMConstInt(LLVMIntType(g->pointer_size_bytes * 8),
2234 variable->type->size_in_bits / 8, false);
2235 LLVMValueRef align_in_bytes = LLVMConstInt(LLVMInt32Type(),
2236 variable->type->align_in_bits / 8, false);
2254 LLVMValueRef byte_count = LLVMConstInt(isize->type_ref, size_bytes, false);
2255 LLVMValueRef align_in_bytes = LLVMConstInt(LLVMInt32Type(), align_bytes, false);
22372256 LLVMValueRef params[] = {
22382257 dest_ptr,
22392258 fill_char,
......@@ -2273,7 +2292,7 @@ static LLVMValueRef gen_symbol(CodeGen *g, AstNode *node) {
22732292 assert(node->type == NodeTypeSymbol);
22742293 VariableTableEntry *variable = node->data.symbol_expr.variable;
22752294 if (variable) {
2276 if (variable->type->size_in_bits == 0) {
2295 if (!type_has_bits(variable->type)) {
22772296 return nullptr;
22782297 } else if (variable->is_ptr) {
22792298 assert(variable->value_ref);
......@@ -2364,7 +2383,7 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) {
23642383static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
23652384 Expr *expr = get_resolved_expr(node);
23662385 if (expr->const_val.ok) {
2367 if (expr->type_entry->size_in_bits == 0) {
2386 if (!type_has_bits(expr->type_entry)) {
23682387 return nullptr;
23692388 } else {
23702389 assert(expr->const_llvm_val);
......@@ -2600,7 +2619,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
26002619 case TypeTableEntryIdErrorUnion:
26012620 {
26022621 TypeTableEntry *child_type = type_entry->data.error.child_type;
2603 if (child_type->size_in_bits == 0) {
2622 if (!type_has_bits(child_type)) {
26042623 uint64_t value = const_val->data.x_err.err ? const_val->data.x_err.err->value : 0;
26052624 return LLVMConstInt(g->err_tag_type->type_ref, value, false);
26062625 } else {
......@@ -2683,7 +2702,7 @@ static void do_code_gen(CodeGen *g) {
26832702
26842703 if (var->type->id == TypeTableEntryIdNumLitFloat ||
26852704 var->type->id == TypeTableEntryIdNumLitInt ||
2686 var->type->size_in_bits == 0)
2705 !type_has_bits(var->type))
26872706 {
26882707 continue;
26892708 }
......@@ -2820,7 +2839,7 @@ static void do_code_gen(CodeGen *g) {
28202839 for (int var_i = 0; var_i < block_context->variable_list.length; var_i += 1) {
28212840 VariableTableEntry *var = block_context->variable_list.at(var_i);
28222841
2823 if (var->type->size_in_bits == 0) {
2842 if (!type_has_bits(var->type)) {
28242843 continue;
28252844 }
28262845
......@@ -2839,7 +2858,8 @@ static void do_code_gen(CodeGen *g) {
28392858
28402859 add_debug_source_node(g, var->decl_node);
28412860 var->value_ref = LLVMBuildAlloca(g->builder, var->type->type_ref, buf_ptr(&var->name));
2842 LLVMSetAlignment(var->value_ref, var->type->align_in_bits / 8);
2861 uint64_t align_bytes = LLVMABISizeOfType(g->target_data_ref, var->type->type_ref);
2862 LLVMSetAlignment(var->value_ref, align_bytes);
28432863 }
28442864
28452865 var->di_loc_var = LLVMZigCreateLocalVariable(g->dbuilder, tag,
......@@ -2953,16 +2973,19 @@ static void define_builtin_types(CodeGen *g) {
29532973 // if this type is anywhere in the AST, we should never hit codegen.
29542974 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInvalid);
29552975 buf_init_from_str(&entry->name, "(invalid)");
2976 entry->zero_bits = true;
29562977 g->builtin_types.entry_invalid = entry;
29572978 }
29582979 {
29592980 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitFloat);
29602981 buf_init_from_str(&entry->name, "(float literal)");
2982 entry->zero_bits = true;
29612983 g->builtin_types.entry_num_lit_float = entry;
29622984 }
29632985 {
29642986 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitInt);
29652987 buf_init_from_str(&entry->name, "(integer literal)");
2988 entry->zero_bits = true;
29662989 g->builtin_types.entry_num_lit_int = entry;
29672990 }
29682991 {
......@@ -2982,12 +3005,13 @@ static void define_builtin_types(CodeGen *g) {
29823005 buf_resize(&entry->name, 0);
29833006 buf_appendf(&entry->name, "%c%d", u_or_i, size_in_bits);
29843007
2985 entry->size_in_bits = size_in_bits;
2986 entry->align_in_bits = size_in_bits;
3008 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref);
3009 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
29873010 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),
2988 entry->size_in_bits, entry->align_in_bits,
3011 debug_size_in_bits, debug_align_in_bits,
29893012 is_signed ? LLVMZigEncoding_DW_ATE_signed() : LLVMZigEncoding_DW_ATE_unsigned());
29903013 entry->data.integral.is_signed = is_signed;
3014 entry->data.integral.bit_count = size_in_bits;
29913015 g->primitive_type_table.put(&entry->name, entry);
29923016
29933017 get_int_type_ptr(g, is_signed, size_in_bits)[0] = entry;
......@@ -3010,13 +3034,14 @@ static void define_builtin_types(CodeGen *g) {
30103034
30113035 buf_init_from_str(&entry->name, info->name);
30123036
3013 entry->size_in_bits = size_in_bits;
3014 entry->align_in_bits = size_in_bits;
3015
3037 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref);
3038 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
30163039 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),
3017 entry->size_in_bits, entry->align_in_bits,
3040 debug_size_in_bits,
3041 debug_align_in_bits,
30183042 is_signed ? LLVMZigEncoding_DW_ATE_signed() : LLVMZigEncoding_DW_ATE_unsigned());
30193043 entry->data.integral.is_signed = is_signed;
3044 entry->data.integral.bit_count = size_in_bits;
30203045 g->primitive_type_table.put(&entry->name, entry);
30213046
30223047 get_c_int_type_ptr(g, info->id)[0] = entry;
......@@ -3026,10 +3051,11 @@ static void define_builtin_types(CodeGen *g) {
30263051 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdBool);
30273052 entry->type_ref = LLVMInt1Type();
30283053 buf_init_from_str(&entry->name, "bool");
3029 entry->size_in_bits = 8;
3030 entry->align_in_bits = 8;
3054 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref);
3055 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
30313056 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),
3032 entry->size_in_bits, entry->align_in_bits,
3057 debug_size_in_bits,
3058 debug_align_in_bits,
30333059 LLVMZigEncoding_DW_ATE_unsigned());
30343060 g->builtin_types.entry_bool = entry;
30353061 g->primitive_type_table.put(&entry->name, entry);
......@@ -3038,12 +3064,14 @@ static void define_builtin_types(CodeGen *g) {
30383064 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
30393065 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);
30403066 buf_init_from_str(&entry->name, "isize");
3041 entry->size_in_bits = g->pointer_size_bytes * 8;
3042 entry->align_in_bits = g->pointer_size_bytes * 8;
30433067 entry->data.integral.is_signed = true;
3068 entry->data.integral.bit_count = g->pointer_size_bytes * 8;
30443069
3070 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref);
3071 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
30453072 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),
3046 entry->size_in_bits, entry->align_in_bits,
3073 debug_size_in_bits,
3074 debug_align_in_bits,
30473075 LLVMZigEncoding_DW_ATE_signed());
30483076 g->builtin_types.entry_isize = entry;
30493077 g->primitive_type_table.put(&entry->name, entry);
......@@ -3052,12 +3080,14 @@ static void define_builtin_types(CodeGen *g) {
30523080 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
30533081 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);
30543082 buf_init_from_str(&entry->name, "usize");
3055 entry->size_in_bits = g->pointer_size_bytes * 8;
3056 entry->align_in_bits = g->pointer_size_bytes * 8;
30573083 entry->data.integral.is_signed = false;
3084 entry->data.integral.bit_count = g->pointer_size_bytes * 8;
30583085
3086 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref);
3087 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
30593088 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),
3060 entry->size_in_bits, entry->align_in_bits,
3089 debug_size_in_bits,
3090 debug_align_in_bits,
30613091 LLVMZigEncoding_DW_ATE_unsigned());
30623092 g->builtin_types.entry_usize = entry;
30633093 g->primitive_type_table.put(&entry->name, entry);
......@@ -3066,10 +3096,13 @@ static void define_builtin_types(CodeGen *g) {
30663096 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
30673097 entry->type_ref = LLVMFloatType();
30683098 buf_init_from_str(&entry->name, "f32");
3069 entry->size_in_bits = 32;
3070 entry->align_in_bits = 32;
3099 entry->data.floating.bit_count = 32;
3100
3101 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref);
3102 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
30713103 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),
3072 entry->size_in_bits, entry->align_in_bits,
3104 debug_size_in_bits,
3105 debug_align_in_bits,
30733106 LLVMZigEncoding_DW_ATE_float());
30743107 g->builtin_types.entry_f32 = entry;
30753108 g->primitive_type_table.put(&entry->name, entry);
......@@ -3078,10 +3111,13 @@ static void define_builtin_types(CodeGen *g) {
30783111 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
30793112 entry->type_ref = LLVMDoubleType();
30803113 buf_init_from_str(&entry->name, "f64");
3081 entry->size_in_bits = 64;
3082 entry->align_in_bits = 64;
3114 entry->data.floating.bit_count = 64;
3115
3116 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref);
3117 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
30833118 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),
3084 entry->size_in_bits, entry->align_in_bits,
3119 debug_size_in_bits,
3120 debug_align_in_bits,
30853121 LLVMZigEncoding_DW_ATE_float());
30863122 g->builtin_types.entry_f64 = entry;
30873123 g->primitive_type_table.put(&entry->name, entry);
......@@ -3090,10 +3126,13 @@ static void define_builtin_types(CodeGen *g) {
30903126 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
30913127 entry->type_ref = LLVMX86FP80Type();
30923128 buf_init_from_str(&entry->name, "c_long_double");
3093 entry->size_in_bits = 128;
3094 entry->align_in_bits = 128;
3129 entry->data.floating.bit_count = 80;
3130
3131 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref);
3132 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
30953133 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),
3096 80, entry->align_in_bits,
3134 debug_size_in_bits,
3135 debug_align_in_bits,
30973136 LLVMZigEncoding_DW_ATE_float());
30983137 g->builtin_types.entry_c_long_double = entry;
30993138 g->primitive_type_table.put(&entry->name, entry);
......@@ -3101,9 +3140,11 @@ static void define_builtin_types(CodeGen *g) {
31013140 {
31023141 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);
31033142 entry->type_ref = LLVMVoidType();
3143 entry->zero_bits = true;
31043144 buf_init_from_str(&entry->name, "void");
31053145 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),
3106 entry->size_in_bits, entry->align_in_bits,
3146 0,
3147 0,
31073148 LLVMZigEncoding_DW_ATE_unsigned());
31083149 g->builtin_types.entry_void = entry;
31093150 g->primitive_type_table.put(&entry->name, entry);
......@@ -3111,6 +3152,7 @@ static void define_builtin_types(CodeGen *g) {
31113152 {
31123153 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUnreachable);
31133154 entry->type_ref = LLVMVoidType();
3155 entry->zero_bits = true;
31143156 buf_init_from_str(&entry->name, "unreachable");
31153157 entry->di_type = g->builtin_types.entry_void->di_type;
31163158 g->builtin_types.entry_unreachable = entry;
......@@ -3119,6 +3161,7 @@ static void define_builtin_types(CodeGen *g) {
31193161 {
31203162 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMetaType);
31213163 buf_init_from_str(&entry->name, "type");
3164 entry->zero_bits = true;
31223165 g->builtin_types.entry_type = entry;
31233166 g->primitive_type_table.put(&entry->name, entry);
31243167 }
......@@ -3212,6 +3255,7 @@ static void define_builtin_fns(CodeGen *g) {
32123255 g->memset_fn_val = builtin_fn->fn_val;
32133256 }
32143257 create_builtin_fn_with_arg_count(g, BuiltinFnIdSizeof, "sizeof", 1);
3258 create_builtin_fn_with_arg_count(g, BuiltinFnIdAlignof, "alignof", 1);
32153259 create_builtin_fn_with_arg_count(g, BuiltinFnIdMaxValue, "max_value", 1);
32163260 create_builtin_fn_with_arg_count(g, BuiltinFnIdMinValue, "min_value", 1);
32173261 create_builtin_fn_with_arg_count(g, BuiltinFnIdMemberCount, "member_count", 1);
src/parseh.cpp+22-25
......@@ -740,8 +740,6 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
740740 enum_type->data.enumeration.complete = true;
741741
742742 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(c->codegen, field_count);
743 enum_type->align_in_bits = tag_type_entry->size_in_bits;
744 enum_type->size_in_bits = tag_type_entry->size_in_bits;
745743 enum_type->data.enumeration.tag_type = tag_type_entry;
746744
747745 c->enum_type_table.put(bare_name, enum_type);
......@@ -795,11 +793,14 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
795793
796794 // create debug type for tag
797795 unsigned line = c->source_node ? (c->source_node->line + 1) : 0;
796 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(c->codegen->target_data_ref, enum_type->type_ref);
797 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, enum_type->type_ref);
798798 LLVMZigDIType *tag_di_type = LLVMZigCreateDebugEnumerationType(c->codegen->dbuilder,
799799 LLVMZigFileToScope(c->import->di_file), buf_ptr(bare_name),
800800 c->import->di_file, line,
801 tag_type_entry->size_in_bits, tag_type_entry->align_in_bits, di_enumerators, field_count,
802 tag_type_entry->di_type, "");
801 debug_size_in_bits,
802 debug_align_in_bits,
803 di_enumerators, field_count, tag_type_entry->di_type, "");
803804
804805 LLVMZigReplaceTemporary(c->codegen->dbuilder, enum_type->di_type, tag_di_type);
805806 enum_type->di_type = tag_di_type;
......@@ -894,10 +895,6 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
894895 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);
895896 LLVMZigDIType **di_element_types = allocate<LLVMZigDIType*>(field_count);
896897
897 uint64_t total_size_in_bits = 0;
898 uint64_t first_field_align_in_bits = 0;
899 uint64_t offset_in_bits = 0;
900
901898 uint32_t i = 0;
902899 for (auto it = record_def->field_begin(),
903900 it_end = record_def->field_end();
......@@ -909,30 +906,29 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
909906 type_struct_field->name = buf_create_from_str(decl_name(field_decl));
910907 type_struct_field->src_index = i;
911908 type_struct_field->gen_index = i;
912 type_struct_field->type_entry = resolve_qual_type(c, field_decl->getType(), field_decl);
909 TypeTableEntry *field_type = resolve_qual_type(c, field_decl->getType(), field_decl);
910 type_struct_field->type_entry = field_type;
913911
914 if (type_struct_field->type_entry->id == TypeTableEntryIdInvalid) {
912 if (field_type->id == TypeTableEntryIdInvalid) {
915913 emit_warning(c, field_decl, "struct %s demoted to typedef - unresolved type\n", buf_ptr(bare_name));
916914 return struct_type;
917915 }
918916
917 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(c->codegen->target_data_ref, field_type->type_ref);
918 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, field_type->type_ref);
919 uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(c->codegen->target_data_ref, struct_type->type_ref, i);
919920 di_element_types[i] = LLVMZigCreateDebugMemberType(c->codegen->dbuilder,
920921 LLVMZigTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name),
921922 c->import->di_file, line + 1,
922 type_struct_field->type_entry->size_in_bits,
923 type_struct_field->type_entry->align_in_bits,
924 offset_in_bits, 0, type_struct_field->type_entry->di_type);
923 debug_size_in_bits,
924 debug_align_in_bits,
925 debug_offset_in_bits,
926 0, field_type->di_type);
925927
926 element_types[i] = type_struct_field->type_entry->type_ref;
928 element_types[i] = field_type->type_ref;
927929 assert(di_element_types[i]);
928930 assert(element_types[i]);
929931
930 total_size_in_bits += type_struct_field->type_entry->size_in_bits;
931 if (first_field_align_in_bits == 0) {
932 first_field_align_in_bits = type_struct_field->type_entry->align_in_bits;
933 }
934 offset_in_bits += type_struct_field->type_entry->size_in_bits;
935
936932 }
937933 struct_type->data.structure.embedded_in_current = false;
938934
......@@ -941,13 +937,14 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
941937
942938 LLVMStructSetBody(struct_type->type_ref, element_types, field_count, false);
943939
944 struct_type->align_in_bits = first_field_align_in_bits;
945 struct_type->size_in_bits = total_size_in_bits;
946
940 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(c->codegen->target_data_ref, struct_type->type_ref);
941 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, struct_type->type_ref);
947942 LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(c->codegen->dbuilder,
948943 LLVMZigFileToScope(c->import->di_file),
949 buf_ptr(full_type_name),
950 c->import->di_file, line + 1, struct_type->size_in_bits, struct_type->align_in_bits, 0,
944 buf_ptr(full_type_name), c->import->di_file, line + 1,
945 debug_size_in_bits,
946 debug_align_in_bits,
947 0,
951948 nullptr, di_element_types, field_count, 0, nullptr, "");
952949
953950 LLVMZigReplaceTemporary(c->codegen->dbuilder, struct_type->di_type, replacement_di_type);
test/run_tests.cpp+8-8
......@@ -379,10 +379,10 @@ pub fn main(args: [][]u8) -> %void {
379379 array[0] = void{};
380380 array[1] = array[2];
381381 if (@sizeof(@typeof(array)) != 0) {
382 %%stdout.printf("BAD\n");
382 %%stdout.printf("BAD sizeof\n");
383383 }
384384 if (array.len != 4) {
385 %%stdout.printf("BAD\n");
385 %%stdout.printf("BAD len\n");
386386 }
387387 %%stdout.printf("OK\n");
388388}
......@@ -1075,22 +1075,22 @@ pub fn main(args: [][]u8) -> %void {
10751075 const bar = Bar.B;
10761076
10771077 if (bar != Bar.B) {
1078 %%stdout.printf("BAD\n");
1078 %%stdout.printf("BAD 1\n");
10791079 }
10801080
10811081 if (@member_count(Foo) != 3) {
1082 %%stdout.printf("BAD\n");
1082 %%stdout.printf("BAD 2\n");
10831083 }
10841084
10851085 if (@member_count(Bar) != 4) {
1086 %%stdout.printf("BAD\n");
1086 %%stdout.printf("BAD 3\n");
10871087 }
10881088
1089 if (@sizeof(Foo) != 17) {
1090 %%stdout.printf("BAD\n");
1089 if (@sizeof(Foo) != 24) {
1090 %%stdout.printf("BAD 4\n");
10911091 }
10921092 if (@sizeof(Bar) != 1) {
1093 %%stdout.printf("BAD\n");
1093 %%stdout.printf("BAD 5\n");
10941094 }
10951095
10961096 %%stdout.printf("OK\n");