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 {...@@ -807,6 +807,11 @@ struct TypeTableEntryPointer {
807807
808struct TypeTableEntryInt {808struct TypeTableEntryInt {
809 bool is_signed;809 bool is_signed;
810 int bit_count;
811};
812
813struct TypeTableEntryFloat {
814 int bit_count;
810};815};
811816
812struct TypeTableEntryArray {817struct TypeTableEntryArray {
...@@ -910,17 +915,17 @@ enum TypeTableEntryId {...@@ -910,17 +915,17 @@ enum TypeTableEntryId {
910915
911struct TypeTableEntry {916struct TypeTableEntry {
912 TypeTableEntryId id;917 TypeTableEntryId id;
918 Buf name;
913919
914 LLVMTypeRef type_ref;920 LLVMTypeRef type_ref;
915 LLVMZigDIType *di_type;921 LLVMZigDIType *di_type;
916 uint64_t size_in_bits;
917 uint64_t align_in_bits;
918922
919 Buf name;923 bool zero_bits;
920924
921 union {925 union {
922 TypeTableEntryPointer pointer;926 TypeTableEntryPointer pointer;
923 TypeTableEntryInt integral;927 TypeTableEntryInt integral;
928 TypeTableEntryFloat floating;
924 TypeTableEntryArray array;929 TypeTableEntryArray array;
925 TypeTableEntryStruct structure;930 TypeTableEntryStruct structure;
926 TypeTableEntryMaybe maybe;931 TypeTableEntryMaybe maybe;
...@@ -988,6 +993,7 @@ enum BuiltinFnId {...@@ -988,6 +993,7 @@ enum BuiltinFnId {
988 BuiltinFnIdMemcpy,993 BuiltinFnIdMemcpy,
989 BuiltinFnIdMemset,994 BuiltinFnIdMemset,
990 BuiltinFnIdSizeof,995 BuiltinFnIdSizeof,
996 BuiltinFnIdAlignof,
991 BuiltinFnIdMaxValue,997 BuiltinFnIdMaxValue,
992 BuiltinFnIdMinValue,998 BuiltinFnIdMinValue,
993 BuiltinFnIdMemberCount,999 BuiltinFnIdMemberCount,
src/analyze.cpp+287-155
...@@ -200,27 +200,21 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool...@@ -200,27 +200,21 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool
200 TypeTableEntry *canon_child_type = get_underlying_type(child_type);200 TypeTableEntry *canon_child_type = get_underlying_type(child_type);
201 assert(canon_child_type->id != TypeTableEntryIdInvalid);201 assert(canon_child_type->id != TypeTableEntryIdInvalid);
202202
203 bool zero_bits;203
204 if (canon_child_type->size_in_bits == 0) {204 if (type_is_complete(canon_child_type)) {
205 if (canon_child_type->id == TypeTableEntryIdStruct) {205 entry->zero_bits = !type_has_bits(canon_child_type);
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 }
212 } else {206 } else {
213 zero_bits = false;207 entry->zero_bits = false;
214 }208 }
215209
216 if (!zero_bits) {210 if (!entry->zero_bits) {
217 entry->type_ref = LLVMPointerType(child_type->type_ref, 0);211 entry->type_ref = LLVMPointerType(child_type->type_ref, 0);
218212
219 entry->size_in_bits = g->pointer_size_bytes * 8;213 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref);
220 entry->align_in_bits = g->pointer_size_bytes * 8;214 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
221 assert(child_type->di_type);215 assert(child_type->di_type);
222 entry->di_type = LLVMZigCreateDebugPointerType(g->dbuilder, child_type->di_type,216 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));
224 }218 }
225219
226 entry->data.pointer.child_type = child_type;220 entry->data.pointer.child_type = child_type;
...@@ -249,8 +243,6 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {...@@ -249,8 +243,6 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {
249 // this is an optimization but also is necessary for calling C243 // this is an optimization but also is necessary for calling C
250 // functions where all pointers are maybe pointers244 // functions where all pointers are maybe pointers
251 // function types are technically pointers245 // 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;
254 entry->type_ref = child_type->type_ref;246 entry->type_ref = child_type->type_ref;
255 entry->di_type = child_type->di_type;247 entry->di_type = child_type->di_type;
256 } else {248 } else {
...@@ -260,8 +252,6 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {...@@ -260,8 +252,6 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {
260 LLVMInt1Type(),252 LLVMInt1Type(),
261 };253 };
262 entry->type_ref = LLVMStructType(elem_types, 2, false);254 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
267 LLVMZigDIScope *compile_unit_scope = LLVMZigCompileUnitToScope(g->compile_unit);257 LLVMZigDIScope *compile_unit_scope = LLVMZigCompileUnitToScope(g->compile_unit);
...@@ -271,18 +261,36 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {...@@ -271,18 +261,36 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {
271 LLVMZigTag_DW_structure_type(), buf_ptr(&entry->name),261 LLVMZigTag_DW_structure_type(), buf_ptr(&entry->name),
272 compile_unit_scope, di_file, line);262 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
274 LLVMZigDIType *di_element_types[] = {276 LLVMZigDIType *di_element_types[] = {
275 LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type),277 LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type),
276 "val", di_file, line, child_type->size_in_bits, child_type->align_in_bits, 0, 0,278 "val", di_file, line,
277 child_type->di_type),279 val_debug_size_in_bits,
280 val_debug_align_in_bits,
281 val_offset_in_bits,
282 0, child_type->di_type),
278 LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type),283 LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type),
279 "maybe", di_file, line, 8, 8, child_type->size_in_bits, 0,284 "maybe", di_file, line,
280 child_type->di_type),285 maybe_debug_size_in_bits,
286 maybe_debug_align_in_bits,
287 maybe_offset_in_bits,
288 0, child_type->di_type),
281 };289 };
282 LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder,290 LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder,
283 compile_unit_scope,291 compile_unit_scope,
284 buf_ptr(&entry->name),292 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,
286 nullptr, di_element_types, 2, 0, nullptr, "");294 nullptr, di_element_types, 2, 0, nullptr, "");
287295
288 LLVMZigReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type);296 LLVMZigReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type);
...@@ -309,10 +317,8 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {...@@ -309,10 +317,8 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
309317
310 entry->data.error.child_type = child_type;318 entry->data.error.child_type = child_type;
311319
312 if (child_type->size_in_bits == 0) {320 if (!type_has_bits(child_type)) {
313 entry->type_ref = g->err_tag_type->type_ref;321 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;
316 entry->di_type = g->err_tag_type->di_type;322 entry->di_type = g->err_tag_type->di_type;
317323
318 } else {324 } else {
...@@ -321,8 +327,6 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {...@@ -321,8 +327,6 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
321 child_type->type_ref,327 child_type->type_ref,
322 };328 };
323 entry->type_ref = LLVMStructType(elem_types, 2, false);329 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
327 LLVMZigDIScope *compile_unit_scope = LLVMZigCompileUnitToScope(g->compile_unit);331 LLVMZigDIScope *compile_unit_scope = LLVMZigCompileUnitToScope(g->compile_unit);
328 LLVMZigDIFile *di_file = nullptr;332 LLVMZigDIFile *di_file = nullptr;
...@@ -331,19 +335,39 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {...@@ -331,19 +335,39 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
331 LLVMZigTag_DW_structure_type(), buf_ptr(&entry->name),335 LLVMZigTag_DW_structure_type(), buf_ptr(&entry->name),
332 compile_unit_scope, di_file, line);336 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
334 LLVMZigDIType *di_element_types[] = {349 LLVMZigDIType *di_element_types[] = {
335 LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type),350 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,351 "tag", di_file, line,
337 0, 0, child_type->di_type),352 tag_debug_size_in_bits,
353 tag_debug_align_in_bits,
354 tag_offset_in_bits,
355 0, child_type->di_type),
338 LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type),356 LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type),
339 "value", di_file, line, child_type->size_in_bits, child_type->align_in_bits,357 "value", di_file, line,
340 g->err_tag_type->size_in_bits, 0, child_type->di_type),358 value_debug_size_in_bits,
359 value_debug_align_in_bits,
360 value_offset_in_bits,
361 0, child_type->di_type),
341 };362 };
342363
343 LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder,364 LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder,
344 compile_unit_scope,365 compile_unit_scope,
345 buf_ptr(&entry->name),366 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,
347 nullptr, di_element_types, 2, 0, nullptr, "");371 nullptr, di_element_types, 2, 0, nullptr, "");
348372
349 LLVMZigReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type);373 LLVMZigReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type);
...@@ -363,14 +387,16 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t...@@ -363,14 +387,16 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t
363 } else {387 } else {
364 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray);388 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray);
365 entry->type_ref = LLVMArrayType(child_type->type_ref, array_size);389 entry->type_ref = LLVMArrayType(child_type->type_ref, array_size);
390 entry->zero_bits = (array_size == 0) || child_type->zero_bits;
391
366 buf_resize(&entry->name, 0);392 buf_resize(&entry->name, 0);
367 buf_appendf(&entry->name, "[%" PRIu64 "]%s", array_size, buf_ptr(&child_type->name));393 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;395 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref);
370 entry->align_in_bits = child_type->align_in_bits;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,398 entry->di_type = LLVMZigCreateDebugArrayType(g->dbuilder, debug_size_in_bits,
373 entry->align_in_bits, child_type->di_type, array_size);399 debug_align_in_bits, child_type->di_type, array_size);
374 entry->data.array.child_type = child_type;400 entry->data.array.child_type = child_type;
375 entry->data.array.len = array_size;401 entry->data.array.len = array_size;
376402
...@@ -379,14 +405,12 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t...@@ -379,14 +405,12 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t
379 }405 }
380}406}
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,
383 bool is_const, TypeTableEntry *entry)409 bool is_const, TypeTableEntry *entry)
384{410{
385 TypeTableEntry *pointer_type = get_pointer_to_type(g, child_type, is_const);411 TypeTableEntry *pointer_type = get_pointer_to_type(g, child_type, is_const);
386412
387 unsigned element_count = 2;413 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;
390 entry->data.structure.is_packed = false;414 entry->data.structure.is_packed = false;
391 entry->data.structure.is_unknown_size_array = true;415 entry->data.structure.is_unknown_size_array = true;
392 entry->data.structure.src_field_count = element_count;416 entry->data.structure.src_field_count = element_count;
...@@ -402,20 +426,20 @@ static void unknown_size_array_type_common_init(CodeGen *g, TypeTableEntry *chil...@@ -402,20 +426,20 @@ static void unknown_size_array_type_common_init(CodeGen *g, TypeTableEntry *chil
402 entry->data.structure.fields[1].gen_index = 1;426 entry->data.structure.fields[1].gen_index = 1;
403}427}
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) {
406 assert(child_type->id != TypeTableEntryIdInvalid);430 assert(child_type->id != TypeTableEntryIdInvalid);
407 TypeTableEntry **parent_pointer = &child_type->unknown_size_array_parent[(is_const ? 1 : 0)];431 TypeTableEntry **parent_pointer = &child_type->unknown_size_array_parent[(is_const ? 1 : 0)];
408432
409 if (*parent_pointer) {433 if (*parent_pointer) {
410 return *parent_pointer;434 return *parent_pointer;
411 } else if (is_const) {435 } 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);
413 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct);437 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct);
414438
415 buf_resize(&entry->name, 0);439 buf_resize(&entry->name, 0);
416 buf_appendf(&entry->name, "[]const %s", buf_ptr(&child_type->name));440 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
420 entry->type_ref = var_peer->type_ref;444 entry->type_ref = var_peer->type_ref;
421 entry->di_type = var_peer->di_type;445 entry->di_type = var_peer->di_type;
...@@ -439,15 +463,17 @@ static TypeTableEntry *get_unknown_size_array_type(CodeGen *g, TypeTableEntry *c...@@ -439,15 +463,17 @@ static TypeTableEntry *get_unknown_size_array_type(CodeGen *g, TypeTableEntry *c
439 };463 };
440 LLVMStructSetBody(entry->type_ref, element_types, element_count, false);464 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
444 LLVMZigDIType *di_element_types[] = {468 LLVMZigDIType *di_element_types[] = {
445 pointer_type->di_type,469 pointer_type->di_type,
446 g->builtin_types.entry_isize->di_type,470 g->builtin_types.entry_isize->di_type,
447 };471 };
448 LLVMZigDIScope *compile_unit_scope = LLVMZigCompileUnitToScope(g->compile_unit);472 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);
449 entry->di_type = LLVMZigCreateDebugStructType(g->dbuilder, compile_unit_scope,475 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,
451 nullptr, di_element_types, element_count, 0, nullptr, "");477 nullptr, di_element_types, element_count, 0, nullptr, "");
452478
453 entry->data.structure.complete = true;479 entry->data.structure.complete = true;
...@@ -462,11 +488,9 @@ TypeTableEntry *get_typedecl_type(CodeGen *g, const char *name, TypeTableEntry *...@@ -462,11 +488,9 @@ TypeTableEntry *get_typedecl_type(CodeGen *g, const char *name, TypeTableEntry *
462488
463 buf_init_from_str(&entry->name, name);489 buf_init_from_str(&entry->name, name);
464490
465 entry->type_ref = child_type->type_ref;
466 entry->type_ref = child_type->type_ref;491 entry->type_ref = child_type->type_ref;
467 entry->di_type = child_type->di_type;492 entry->di_type = child_type->di_type;
468 entry->size_in_bits = child_type->size_in_bits;493 entry->zero_bits = child_type->zero_bits;
469 entry->align_in_bits = child_type->align_in_bits;
470494
471 entry->data.type_decl.child_type = child_type;495 entry->data.type_decl.child_type = child_type;
472496
...@@ -497,9 +521,6 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId fn_type_id) {...@@ -497,9 +521,6 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId fn_type_id) {
497 fn_type->data.fn.calling_convention = LLVMFastCallConv;521 fn_type->data.fn.calling_convention = LLVMFastCallConv;
498 }522 }
499523
500 fn_type->size_in_bits = g->pointer_size_bytes * 8;
501 fn_type->align_in_bits = g->pointer_size_bytes * 8;
502
503 // populate the name of the type524 // populate the name of the type
504 buf_resize(&fn_type->name, 0);525 buf_resize(&fn_type->name, 0);
505 const char *extern_str = fn_type_id.is_extern ? "extern " : "";526 const char *extern_str = fn_type_id.is_extern ? "extern " : "";
...@@ -542,7 +563,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId fn_type_id) {...@@ -542,7 +563,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId fn_type_id) {
542 // after the gen_param_index += 1 because 0 is the return type563 // after the gen_param_index += 1 because 0 is the return type
543 param_di_types[gen_param_index] = gen_type->di_type;564 param_di_types[gen_param_index] = gen_type->di_type;
544 gen_return_type = g->builtin_types.entry_void;565 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)) {
546 gen_return_type = g->builtin_types.entry_void;567 gen_return_type = g->builtin_types.entry_void;
547 } else {568 } else {
548 gen_return_type = fn_type_id.return_type;569 gen_return_type = fn_type_id.return_type;
...@@ -559,7 +580,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId fn_type_id) {...@@ -559,7 +580,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId fn_type_id) {
559 gen_param_info->gen_index = -1;580 gen_param_info->gen_index = -1;
560581
561 assert(type_is_complete(type_entry));582 assert(type_is_complete(type_entry));
562 if (type_entry->size_in_bits > 0) {583 if (type_has_bits(type_entry)) {
563 TypeTableEntry *gen_type;584 TypeTableEntry *gen_type;
564 if (handle_is_ptr(type_entry)) {585 if (handle_is_ptr(type_entry)) {
565 gen_type = get_pointer_to_type(g, type_entry, true);586 gen_type = get_pointer_to_type(g, type_entry, true);
...@@ -897,37 +918,43 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt...@@ -897,37 +918,43 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
897 AstNode *field_node = decl_node->data.struct_decl.fields.at(i);918 AstNode *field_node = decl_node->data.struct_decl.fields.at(i);
898 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i];919 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i];
899 type_enum_field->name = &field_node->data.struct_field.name;920 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,
901 field_node->data.struct_field.type);922 field_node->data.struct_field.type);
923 type_enum_field->type_entry = field_type;
902 type_enum_field->value = i;924 type_enum_field->value = i;
903925
926
904 di_enumerators[i] = LLVMZigCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i);927 di_enumerators[i] = LLVMZigCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i);
905928
906 if (type_enum_field->type_entry->id == TypeTableEntryIdStruct) {929 if (field_type->id == TypeTableEntryIdStruct) {
907 resolve_struct_type(g, import, type_enum_field->type_entry);930 resolve_struct_type(g, import, field_type);
908 } else if (type_enum_field->type_entry->id == TypeTableEntryIdEnum) {931 } else if (field_type->id == TypeTableEntryIdEnum) {
909 resolve_enum_type(g, import, type_enum_field->type_entry);932 resolve_enum_type(g, import, field_type);
910 } else if (type_enum_field->type_entry->id == TypeTableEntryIdInvalid) {933 } else if (field_type->id == TypeTableEntryIdInvalid) {
911 enum_type->data.enumeration.is_invalid = true;934 enum_type->data.enumeration.is_invalid = true;
912 continue;935 continue;
913 } else if (type_enum_field->type_entry->id == TypeTableEntryIdVoid) {936 } else if (!type_has_bits(field_type)) {
914 continue;937 continue;
915 }938 }
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
917 union_inner_di_types[gen_field_index] = LLVMZigCreateDebugMemberType(g->dbuilder,943 union_inner_di_types[gen_field_index] = LLVMZigCreateDebugMemberType(g->dbuilder,
918 LLVMZigTypeToScope(enum_type->di_type), buf_ptr(type_enum_field->name),944 LLVMZigTypeToScope(enum_type->di_type), buf_ptr(type_enum_field->name),
919 import->di_file, field_node->line + 1,945 import->di_file, field_node->line + 1,
920 type_enum_field->type_entry->size_in_bits,946 debug_size_in_bits,
921 type_enum_field->type_entry->align_in_bits,947 debug_align_in_bits,
922 0, 0, type_enum_field->type_entry->di_type);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
926 if (!biggest_union_member ||953 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)
928 {955 {
929 biggest_union_member = type_enum_field->type_entry;956 biggest_union_member = field_type;
930 biggest_union_member_size_in_bits = biggest_union_member->size_in_bits;957 biggest_union_member_size_in_bits = debug_size_in_bits;
931 }958 }
932959
933 gen_field_index += 1;960 gen_field_index += 1;
...@@ -941,8 +968,6 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt...@@ -941,8 +968,6 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
941 enum_type->data.enumeration.gen_field_count = gen_field_index;968 enum_type->data.enumeration.gen_field_count = gen_field_index;
942969
943 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);970 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;
946 enum_type->data.enumeration.tag_type = tag_type_entry;971 enum_type->data.enumeration.tag_type = tag_type_entry;
947972
948 if (biggest_union_member) {973 if (biggest_union_member) {
...@@ -958,30 +983,37 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt...@@ -958,30 +983,37 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
958 LLVMStructSetBody(enum_type->type_ref, root_struct_element_types, 2, false);983 LLVMStructSetBody(enum_type->type_ref, root_struct_element_types, 2, false);
959984
960 // create debug type for tag985 // 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);
961 LLVMZigDIType *tag_di_type = LLVMZigCreateDebugEnumerationType(g->dbuilder,988 LLVMZigDIType *tag_di_type = LLVMZigCreateDebugEnumerationType(g->dbuilder,
962 LLVMZigTypeToScope(enum_type->di_type), "AnonEnum", import->di_file, decl_node->line + 1,989 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,
964 tag_type_entry->di_type, "");991 tag_type_entry->di_type, "");
965992
966 // create debug type for union993 // create debug type for union
967 LLVMZigDIType *union_di_type = LLVMZigCreateDebugUnionType(g->dbuilder,994 LLVMZigDIType *union_di_type = LLVMZigCreateDebugUnionType(g->dbuilder,
968 LLVMZigTypeToScope(enum_type->di_type), "AnonUnion", import->di_file, decl_node->line + 1,995 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,
970 gen_field_index, 0, "");997 gen_field_index, 0, "");
971998
972 // create debug types for members of root struct999 // 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);
973 LLVMZigDIType *tag_member_di_type = LLVMZigCreateDebugMemberType(g->dbuilder,1001 LLVMZigDIType *tag_member_di_type = LLVMZigCreateDebugMemberType(g->dbuilder,
974 LLVMZigTypeToScope(enum_type->di_type), "tag_field",1002 LLVMZigTypeToScope(enum_type->di_type), "tag_field",
975 import->di_file, decl_node->line + 1,1003 import->di_file, decl_node->line + 1,
976 tag_type_entry->size_in_bits,1004 tag_debug_size_in_bits,
977 tag_type_entry->align_in_bits,1005 tag_debug_align_in_bits,
978 0, 0, tag_di_type);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);
979 LLVMZigDIType *union_member_di_type = LLVMZigCreateDebugMemberType(g->dbuilder,1010 LLVMZigDIType *union_member_di_type = LLVMZigCreateDebugMemberType(g->dbuilder,
980 LLVMZigTypeToScope(enum_type->di_type), "union_field",1011 LLVMZigTypeToScope(enum_type->di_type), "union_field",
981 import->di_file, decl_node->line + 1,1012 import->di_file, decl_node->line + 1,
982 biggest_union_member->size_in_bits,1013 biggest_union_member_size_in_bits,
983 biggest_align_in_bits,1014 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
986 // create debug type for root struct1018 // create debug type for root struct
987 LLVMZigDIType *di_root_members[] = {1019 LLVMZigDIType *di_root_members[] = {
...@@ -990,11 +1022,15 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt...@@ -990,11 +1022,15 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
990 };1022 };
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);
993 LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder,1027 LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder,
994 LLVMZigFileToScope(import->di_file),1028 LLVMZigFileToScope(import->di_file),
995 buf_ptr(&decl_node->data.struct_decl.name),1029 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,1030 import->di_file, decl_node->line + 1,
997 nullptr, di_root_members, 2, 0, nullptr, "");1031 debug_size_in_bits,
1032 debug_align_in_bits,
1033 0, nullptr, di_root_members, 2, 0, nullptr, "");
9981034
999 LLVMZigReplaceTemporary(g->dbuilder, enum_type->di_type, replacement_di_type);1035 LLVMZigReplaceTemporary(g->dbuilder, enum_type->di_type, replacement_di_type);
1000 enum_type->di_type = replacement_di_type;1036 enum_type->di_type = replacement_di_type;
...@@ -1003,10 +1039,14 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt...@@ -1003,10 +1039,14 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
1003 enum_type->type_ref = tag_type_entry->type_ref;1039 enum_type->type_ref = tag_type_entry->type_ref;
10041040
1005 // create debug type for tag1041 // 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);
1006 LLVMZigDIType *tag_di_type = LLVMZigCreateDebugEnumerationType(g->dbuilder,1044 LLVMZigDIType *tag_di_type = LLVMZigCreateDebugEnumerationType(g->dbuilder,
1007 LLVMZigFileToScope(import->di_file), buf_ptr(&decl_node->data.struct_decl.name),1045 LLVMZigFileToScope(import->di_file), buf_ptr(&decl_node->data.struct_decl.name),
1008 import->di_file, decl_node->line + 1,1046 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,
1010 tag_type_entry->di_type, "");1050 tag_type_entry->di_type, "");
10111051
1012 LLVMZigReplaceTemporary(g->dbuilder, enum_type->di_type, tag_di_type);1052 LLVMZigReplaceTemporary(g->dbuilder, enum_type->di_type, tag_di_type);
...@@ -1025,6 +1065,7 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE...@@ -1025,6 +1065,7 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
1025 AstNode *decl_node = struct_type->data.structure.decl_node;1065 AstNode *decl_node = struct_type->data.structure.decl_node;
10261066
1027 if (struct_type->data.structure.embedded_in_current) {1067 if (struct_type->data.structure.embedded_in_current) {
1068 struct_type->data.structure.is_invalid = true;
1028 if (!struct_type->data.structure.reported_infinite_err) {1069 if (!struct_type->data.structure.reported_infinite_err) {
1029 struct_type->data.structure.reported_infinite_err = true;1070 struct_type->data.structure.reported_infinite_err = true;
1030 add_node_error(g, decl_node,1071 add_node_error(g, decl_node,
...@@ -1049,11 +1090,6 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE...@@ -1049,11 +1090,6 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
1049 // we possibly allocate too much here since gen_field_count can be lower than field_count.1090 // we possibly allocate too much here since gen_field_count can be lower than field_count.
1050 // the only problem is potential wasted space though.1091 // the only problem is potential wasted space though.
1051 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);1092 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
1058 // this field should be set to true only during the recursive calls to resolve_struct_type1094 // this field should be set to true only during the recursive calls to resolve_struct_type
1059 struct_type->data.structure.embedded_in_current = true;1095 struct_type->data.structure.embedded_in_current = true;
...@@ -1063,41 +1099,28 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE...@@ -1063,41 +1099,28 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
1063 AstNode *field_node = decl_node->data.struct_decl.fields.at(i);1099 AstNode *field_node = decl_node->data.struct_decl.fields.at(i);
1064 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];1100 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
1065 type_struct_field->name = &field_node->data.struct_field.name;1101 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,
1067 field_node->data.struct_field.type);1103 field_node->data.struct_field.type);
1104 type_struct_field->type_entry = field_type;
1068 type_struct_field->src_index = i;1105 type_struct_field->src_index = i;
1069 type_struct_field->gen_index = -1;1106 type_struct_field->gen_index = -1;
10701107
1071 if (type_struct_field->type_entry->id == TypeTableEntryIdStruct) {1108 if (field_type->id == TypeTableEntryIdStruct) {
1072 resolve_struct_type(g, import, type_struct_field->type_entry);1109 resolve_struct_type(g, import, field_type);
1073 } else if (type_struct_field->type_entry->id == TypeTableEntryIdEnum) {1110 } else if (field_type->id == TypeTableEntryIdEnum) {
1074 resolve_enum_type(g, import, type_struct_field->type_entry);1111 resolve_enum_type(g, import, field_type);
1075 } else if (type_struct_field->type_entry->id == TypeTableEntryIdInvalid) {1112 } else if (field_type->id == TypeTableEntryIdInvalid) {
1076 struct_type->data.structure.is_invalid = true;1113 struct_type->data.structure.is_invalid = true;
1077 continue;1114 continue;
1078 } else if (type_struct_field->type_entry->id == TypeTableEntryIdVoid) {1115 } else if (!type_has_bits(field_type)) {
1079 continue;1116 continue;
1080 }1117 }
10811118
1082 type_struct_field->gen_index = gen_field_index;1119 type_struct_field->gen_index = gen_field_index;
10831120
1084 di_element_types[gen_field_index] = LLVMZigCreateDebugMemberType(g->dbuilder,1121 element_types[gen_field_index] = field_type->type_ref;
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]);
1093 assert(element_types[gen_field_index]);1122 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
1101 gen_field_index += 1;1124 gen_field_index += 1;
1102 }1125 }
1103 struct_type->data.structure.embedded_in_current = false;1126 struct_type->data.structure.embedded_in_current = false;
...@@ -1105,22 +1128,55 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE...@@ -1105,22 +1128,55 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
1105 struct_type->data.structure.gen_field_count = gen_field_index;1128 struct_type->data.structure.gen_field_count = gen_field_index;
1106 struct_type->data.structure.complete = true;1129 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;1138 LLVMZigDIType **di_element_types = allocate<LLVMZigDIType*>(gen_field_count);
1113 struct_type->size_in_bits = total_size_in_bits;
11141139
1115 LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder,1140 for (int i = 0; i < field_count; i += 1) {
1116 LLVMZigFileToScope(import->di_file),1141 AstNode *field_node = decl_node->data.struct_decl.fields.at(i);
1117 buf_ptr(&decl_node->data.struct_decl.name),1142 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
1118 import->di_file, decl_node->line + 1, struct_type->size_in_bits, struct_type->align_in_bits, 0,1143 gen_field_index = type_struct_field->gen_index;
1119 nullptr, di_element_types, gen_field_index, 0, nullptr, "");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);1162 assert(di_element_types[gen_field_index]);
1122 struct_type->di_type = replacement_di_type;
1123 }1163 }
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);
1124}1180}
11251181
1126static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,1182static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,
...@@ -1498,7 +1554,7 @@ static void add_global_const_expr(CodeGen *g, Expr *expr) {...@@ -1498,7 +1554,7 @@ static void add_global_const_expr(CodeGen *g, Expr *expr) {
1498 if (expr->const_val.ok &&1554 if (expr->const_val.ok &&
1499 type_has_codegen_value(expr->type_entry) &&1555 type_has_codegen_value(expr->type_entry) &&
1500 !expr->has_global_const &&1556 !expr->has_global_const &&
1501 expr->type_entry->size_in_bits > 0)1557 type_has_bits(expr->type_entry))
1502 {1558 {
1503 g->global_const_list.append(expr);1559 g->global_const_list.append(expr);
1504 expr->has_global_const = true;1560 expr->has_global_const = true;
...@@ -1517,7 +1573,7 @@ static bool num_lit_fits_in_other_type(CodeGen *g, AstNode *literal_node, TypeTa...@@ -1517,7 +1573,7 @@ static bool num_lit_fits_in_other_type(CodeGen *g, AstNode *literal_node, TypeTa
1517 } else if (other_type->id == TypeTableEntryIdInt &&1573 } else if (other_type->id == TypeTableEntryIdInt &&
1518 const_val->data.x_bignum.kind == BigNumKindInt)1574 const_val->data.x_bignum.kind == BigNumKindInt)
1519 {1575 {
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,
1521 other_type->data.integral.is_signed))1577 other_type->data.integral.is_signed))
1522 {1578 {
1523 return true;1579 return true;
...@@ -1653,14 +1709,14 @@ static TypeTableEntry *determine_peer_type_compatibility(CodeGen *g, AstNode *pa...@@ -1653,14 +1709,14 @@ static TypeTableEntry *determine_peer_type_compatibility(CodeGen *g, AstNode *pa
1653 cur_type->id == TypeTableEntryIdInt &&1709 cur_type->id == TypeTableEntryIdInt &&
1654 prev_type->data.integral.is_signed == cur_type->data.integral.is_signed)1710 prev_type->data.integral.is_signed == cur_type->data.integral.is_signed)
1655 {1711 {
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) {
1657 prev_type = cur_type;1713 prev_type = cur_type;
1658 prev_node = cur_node;1714 prev_node = cur_node;
1659 }1715 }
1660 } else if (prev_type->id == TypeTableEntryIdFloat &&1716 } else if (prev_type->id == TypeTableEntryIdFloat &&
1661 cur_type->id == TypeTableEntryIdFloat)1717 cur_type->id == TypeTableEntryIdFloat)
1662 {1718 {
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) {
1664 prev_type = cur_type;1720 prev_type = cur_type;
1665 prev_node = cur_node;1721 prev_node = cur_node;
1666 }1722 }
...@@ -1737,7 +1793,7 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_...@@ -1737,7 +1793,7 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_
1737 if (expected_type->id == TypeTableEntryIdInt &&1793 if (expected_type->id == TypeTableEntryIdInt &&
1738 actual_type->id == TypeTableEntryIdInt &&1794 actual_type->id == TypeTableEntryIdInt &&
1739 expected_type->data.integral.is_signed == actual_type->data.integral.is_signed &&1795 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)
1741 {1797 {
1742 return true;1798 return true;
1743 }1799 }
...@@ -1745,7 +1801,7 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_...@@ -1745,7 +1801,7 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_
1745 // implicit float widening conversion1801 // implicit float widening conversion
1746 if (expected_type->id == TypeTableEntryIdFloat &&1802 if (expected_type->id == TypeTableEntryIdFloat &&
1747 actual_type->id == TypeTableEntryIdFloat &&1803 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)
1749 {1805 {
1750 return true;1806 return true;
1751 }1807 }
...@@ -2221,15 +2277,15 @@ static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import,...@@ -2221,15 +2277,15 @@ static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import,
2221 if (array_type->id == TypeTableEntryIdInvalid) {2277 if (array_type->id == TypeTableEntryIdInvalid) {
2222 return_type = g->builtin_types.entry_invalid;2278 return_type = g->builtin_types.entry_invalid;
2223 } else if (array_type->id == TypeTableEntryIdArray) {2279 } 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,
2225 node->data.slice_expr.is_const);2281 node->data.slice_expr.is_const);
2226 } else if (array_type->id == TypeTableEntryIdPointer) {2282 } 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,
2228 node->data.slice_expr.is_const);2284 node->data.slice_expr.is_const);
2229 } else if (array_type->id == TypeTableEntryIdStruct &&2285 } else if (array_type->id == TypeTableEntryIdStruct &&
2230 array_type->data.structure.is_unknown_size_array)2286 array_type->data.structure.is_unknown_size_array)
2231 {2287 {
2232 return_type = get_unknown_size_array_type(g,2288 return_type = get_slice_type(g,
2233 array_type->data.structure.fields[0].type_entry->data.pointer.child_type,2289 array_type->data.structure.fields[0].type_entry->data.pointer.child_type,
2234 node->data.slice_expr.is_const);2290 node->data.slice_expr.is_const);
2235 } else {2291 } else {
...@@ -2666,7 +2722,7 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im...@@ -2666,7 +2722,7 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im
2666 bool are_equal = false;2722 bool are_equal = false;
2667 if (enum1->tag == enum2->tag) {2723 if (enum1->tag == enum2->tag) {
2668 TypeEnumField *enum_field = &op1_type->data.enumeration.fields[enum1->tag];2724 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)) {
2670 zig_panic("TODO const expr analyze enum special value for equality");2726 zig_panic("TODO const expr analyze enum special value for equality");
2671 } else {2727 } else {
2672 are_equal = true;2728 are_equal = true;
...@@ -2839,7 +2895,7 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import,...@@ -2839,7 +2895,7 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import,
2839 AstNode **op1 = node->data.bin_op_expr.op1->parent_field;2895 AstNode **op1 = node->data.bin_op_expr.op1->parent_field;
2840 AstNode **op2 = node->data.bin_op_expr.op2->parent_field;2896 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
2844 TypeTableEntry *op1_type = analyze_expression(g, import, context, str_type, *op1);2900 TypeTableEntry *op1_type = analyze_expression(g, import, context, str_type, *op1);
2845 TypeTableEntry *op2_type = analyze_expression(g, import, context, str_type, *op2);2901 TypeTableEntry *op2_type = analyze_expression(g, import, context, str_type, *op2);
...@@ -3162,11 +3218,11 @@ static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import,...@@ -3162,11 +3218,11 @@ static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import,
3162 }3218 }
3163 } else {3219 } else {
3164 return resolve_expr_const_val_as_type(g, node,3220 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));
3166 }3222 }
3167 } else {3223 } else {
3168 return resolve_expr_const_val_as_type(g, node,3224 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));
3170 }3226 }
3171}3227}
31723228
...@@ -3357,13 +3413,13 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor...@@ -3357,13 +3413,13 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor
3357 if (is_max) {3413 if (is_max) {
3358 if (type_entry->data.integral.is_signed) {3414 if (type_entry->data.integral.is_signed) {
3359 int64_t val;3415 int64_t val;
3360 if (type_entry->size_in_bits == 64) {3416 if (type_entry->data.integral.bit_count == 64) {
3361 val = INT64_MAX;3417 val = INT64_MAX;
3362 } else if (type_entry->size_in_bits == 32) {3418 } else if (type_entry->data.integral.bit_count == 32) {
3363 val = INT32_MAX;3419 val = INT32_MAX;
3364 } else if (type_entry->size_in_bits == 16) {3420 } else if (type_entry->data.integral.bit_count == 16) {
3365 val = INT16_MAX;3421 val = INT16_MAX;
3366 } else if (type_entry->size_in_bits == 8) {3422 } else if (type_entry->data.integral.bit_count == 8) {
3367 val = INT8_MAX;3423 val = INT8_MAX;
3368 } else {3424 } else {
3369 zig_unreachable();3425 zig_unreachable();
...@@ -3371,13 +3427,13 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor...@@ -3371,13 +3427,13 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor
3371 bignum_init_signed(&const_val->data.x_bignum, val);3427 bignum_init_signed(&const_val->data.x_bignum, val);
3372 } else {3428 } else {
3373 uint64_t val;3429 uint64_t val;
3374 if (type_entry->size_in_bits == 64) {3430 if (type_entry->data.integral.bit_count == 64) {
3375 val = UINT64_MAX;3431 val = UINT64_MAX;
3376 } else if (type_entry->size_in_bits == 32) {3432 } else if (type_entry->data.integral.bit_count == 32) {
3377 val = UINT32_MAX;3433 val = UINT32_MAX;
3378 } else if (type_entry->size_in_bits == 16) {3434 } else if (type_entry->data.integral.bit_count == 16) {
3379 val = UINT16_MAX;3435 val = UINT16_MAX;
3380 } else if (type_entry->size_in_bits == 8) {3436 } else if (type_entry->data.integral.bit_count == 8) {
3381 val = UINT8_MAX;3437 val = UINT8_MAX;
3382 } else {3438 } else {
3383 zig_unreachable();3439 zig_unreachable();
...@@ -3387,13 +3443,13 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor...@@ -3387,13 +3443,13 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor
3387 } else {3443 } else {
3388 if (type_entry->data.integral.is_signed) {3444 if (type_entry->data.integral.is_signed) {
3389 int64_t val;3445 int64_t val;
3390 if (type_entry->size_in_bits == 64) {3446 if (type_entry->data.integral.bit_count == 64) {
3391 val = INT64_MIN;3447 val = INT64_MIN;
3392 } else if (type_entry->size_in_bits == 32) {3448 } else if (type_entry->data.integral.bit_count == 32) {
3393 val = INT32_MIN;3449 val = INT32_MIN;
3394 } else if (type_entry->size_in_bits == 16) {3450 } else if (type_entry->data.integral.bit_count == 16) {
3395 val = INT16_MIN;3451 val = INT16_MIN;
3396 } else if (type_entry->size_in_bits == 8) {3452 } else if (type_entry->data.integral.bit_count == 8) {
3397 val = INT8_MIN;3453 val = INT8_MIN;
3398 } else {3454 } else {
3399 zig_unreachable();3455 zig_unreachable();
...@@ -3657,14 +3713,16 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B...@@ -3657,14 +3713,16 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
36573713
3658 // explicit cast from %void to integer type which can fit it3714 // explicit cast from %void to integer type which can fit it
3659 bool actual_type_is_void_err = actual_type->id == TypeTableEntryIdErrorUnion &&3715 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);
3661 bool actual_type_is_pure_err = actual_type->id == TypeTableEntryIdPureError;3717 bool actual_type_is_pure_err = actual_type->id == TypeTableEntryIdPureError;
3662 if ((actual_type_is_void_err || actual_type_is_pure_err) &&3718 if ((actual_type_is_void_err || actual_type_is_pure_err) &&
3663 wanted_type->id == TypeTableEntryIdInt)3719 wanted_type->id == TypeTableEntryIdInt)
3664 {3720 {
3665 BigNum bn;3721 BigNum bn;
3666 bignum_init_unsigned(&bn, g->error_value_count);3722 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 {
3668 node->data.fn_call_expr.cast_op = CastOpErrToInt;3726 node->data.fn_call_expr.cast_op = CastOpErrToInt;
3669 eval_const_expr_implicit_cast(g, node, expr_node);3727 eval_const_expr_implicit_cast(g, node, expr_node);
3670 return wanted_type;3728 return wanted_type;
...@@ -3767,13 +3825,13 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry...@@ -3767,13 +3825,13 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
3767 if (dest_type->id == TypeTableEntryIdPointer &&3825 if (dest_type->id == TypeTableEntryIdPointer &&
3768 src_type->id == TypeTableEntryIdPointer)3826 src_type->id == TypeTableEntryIdPointer)
3769 {3827 {
3770 uint64_t dest_align_bits = dest_type->data.pointer.child_type->align_in_bits;3828 uint64_t dest_align = get_memcpy_align(g, dest_type->data.pointer.child_type);
3771 uint64_t src_align_bits = src_type->data.pointer.child_type->align_in_bits;3829 uint64_t src_align = get_memcpy_align(g, src_type->data.pointer.child_type);
3772 if (dest_align_bits != src_align_bits) {3830 if (dest_align != src_align) {
3773 add_node_error(g, dest_node, buf_sprintf(3831 add_node_error(g, dest_node, buf_sprintf(
3774 "misaligned memcpy, '%s' has alignment '%" PRIu64 ", '%s' has alignment %" PRIu64,3832 "misaligned memcpy, '%s' has alignment '%" PRIu64 ", '%s' has alignment %" PRIu64,
3775 buf_ptr(&dest_type->name), dest_align_bits / 8,3833 buf_ptr(&dest_type->name), dest_align,
3776 buf_ptr(&src_type->name), src_align_bits / 8));3834 buf_ptr(&src_type->name), src_align));
3777 }3835 }
3778 }3836 }
37793837
...@@ -3808,10 +3866,30 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry...@@ -3808,10 +3866,30 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
3808 buf_sprintf("no size available for type '%s'", buf_ptr(&type_entry->name)));3866 buf_sprintf("no size available for type '%s'", buf_ptr(&type_entry->name)));
3809 return g->builtin_types.entry_invalid;3867 return g->builtin_types.entry_invalid;
3810 } else {3868 } 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 }
3812 return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type, size_in_bytes);3875 return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type, size_in_bytes);
3813 }3876 }
3814 }3877 }
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 }
3815 case BuiltinFnIdMaxValue:3893 case BuiltinFnIdMaxValue:
3816 return analyze_min_max_value(g, import, context, node,3894 return analyze_min_max_value(g, import, context, node,
3817 "no max value available for type '%s'", true);3895 "no max value available for type '%s'", true);
...@@ -3874,7 +3952,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry...@@ -3874,7 +3952,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
3874 }3952 }
38753953
3876 AstNode **str_node = node->data.fn_call_expr.params.at(0)->parent_field;3954 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);
3878 TypeTableEntry *resolved_type = analyze_expression(g, import, context, str_type, *str_node);3956 TypeTableEntry *resolved_type = analyze_expression(g, import, context, str_type, *str_node);
38793957
3880 if (resolved_type->id == TypeTableEntryIdInvalid) {3958 if (resolved_type->id == TypeTableEntryIdInvalid) {
...@@ -3911,7 +3989,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry...@@ -3911,7 +3989,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
3911 {3989 {
3912 AstNode **str_node = node->data.fn_call_expr.params.at(0)->parent_field;3990 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);
3915 TypeTableEntry *resolved_type = analyze_expression(g, import, context, str_type, *str_node);3993 TypeTableEntry *resolved_type = analyze_expression(g, import, context, str_type, *str_node);
39163994
3917 if (resolved_type->id == TypeTableEntryIdInvalid) {3995 if (resolved_type->id == TypeTableEntryIdInvalid) {
...@@ -5317,8 +5395,6 @@ void semantic_analyze(CodeGen *g) {...@@ -5317,8 +5395,6 @@ void semantic_analyze(CodeGen *g) {
5317 g->err_tag_type = get_smallest_unsigned_int_type(g, g->error_value_count);5395 g->err_tag_type = get_smallest_unsigned_int_type(g, g->error_value_count);
53185396
5319 g->builtin_types.entry_pure_error->type_ref = g->err_tag_type->type_ref;5397 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;
5322 g->builtin_types.entry_pure_error->di_type = g->err_tag_type->di_type;5398 g->builtin_types.entry_pure_error->di_type = g->err_tag_type->di_type;
5323 }5399 }
53245400
...@@ -5571,7 +5647,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {...@@ -5571,7 +5647,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
5571 case TypeTableEntryIdStruct:5647 case TypeTableEntryIdStruct:
5572 return true;5648 return true;
5573 case TypeTableEntryIdErrorUnion:5649 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);
5575 case TypeTableEntryIdEnum:5651 case TypeTableEntryIdEnum:
5576 return type_entry->data.enumeration.gen_field_count != 0;5652 return type_entry->data.enumeration.gen_field_count != 0;
5577 case TypeTableEntryIdMaybe:5653 case TypeTableEntryIdMaybe:
...@@ -5640,3 +5716,59 @@ bool fn_type_id_eql(FnTypeId a, FnTypeId b) {...@@ -5640,3 +5716,59 @@ bool fn_type_id_eql(FnTypeId a, FnTypeId b) {
5640 }5716 }
5641 return true;5717 return true;
5642}5718}
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);...@@ -35,5 +35,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry);
35void find_libc_path(CodeGen *g);35void find_libc_path(CodeGen *g);
3636
37TypeTableEntry *get_underlying_type(TypeTableEntry *type_entry);37TypeTableEntry *get_underlying_type(TypeTableEntry *type_entry);
38bool type_has_bits(TypeTableEntry *type_entry);
39uint64_t get_memcpy_align(CodeGen *g, TypeTableEntry *type_entry);
3840
39#endif41#endif
src/codegen.cpp+106-62
...@@ -145,8 +145,9 @@ static int bits_index(int size_in_bits) {...@@ -145,8 +145,9 @@ static int bits_index(int size_in_bits) {
145static LLVMValueRef get_arithmetic_overflow_fn(CodeGen *g, TypeTableEntry *type_entry,145static LLVMValueRef get_arithmetic_overflow_fn(CodeGen *g, TypeTableEntry *type_entry,
146 const char *signed_name, const char *unsigned_name)146 const char *signed_name, const char *unsigned_name)
147{147{
148 assert(type_entry->id == TypeTableEntryIdInt);
148 const char *signed_str = type_entry->data.integral.is_signed ? signed_name : unsigned_name;149 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
151 LLVMTypeRef return_elem_types[] = {152 LLVMTypeRef return_elem_types[] = {
152 type_entry->type_ref,153 type_entry->type_ref,
...@@ -168,7 +169,7 @@ static LLVMValueRef get_int_overflow_fn(CodeGen *g, TypeTableEntry *type_entry,...@@ -168,7 +169,7 @@ static LLVMValueRef get_int_overflow_fn(CodeGen *g, TypeTableEntry *type_entry,
168 // [0-signed,1-unsigned][0-add,1-sub,2-mul][0-8,1-16,2-32,3-64]169 // [0-signed,1-unsigned][0-add,1-sub,2-mul][0-8,1-16,2-32,3-64]
169 int index0 = type_entry->data.integral.is_signed ? 0 : 1;170 int index0 = type_entry->data.integral.is_signed ? 0 : 1;
170 int index1 = add_sub_mul;171 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);
172 LLVMValueRef *fn = &g->int_overflow_fns[index0][index1][index2];173 LLVMValueRef *fn = &g->int_overflow_fns[index0][index1][index2];
173 if (*fn) {174 if (*fn) {
174 return *fn;175 return *fn;
...@@ -188,7 +189,6 @@ static LLVMValueRef get_int_overflow_fn(CodeGen *g, TypeTableEntry *type_entry,...@@ -188,7 +189,6 @@ static LLVMValueRef get_int_overflow_fn(CodeGen *g, TypeTableEntry *type_entry,
188 return *fn;189 return *fn;
189}190}
190191
191
192static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {192static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
193 assert(node->type == NodeTypeFnCallExpr);193 assert(node->type == NodeTypeFnCallExpr);
194 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;194 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) {...@@ -257,7 +257,7 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
257 LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, "");257 LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, "");
258 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr, ptr_u8, "");258 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
262 LLVMValueRef params[] = {262 LLVMValueRef params[] = {
263 dest_ptr_casted, // dest pointer263 dest_ptr_casted, // dest pointer
...@@ -287,7 +287,7 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {...@@ -287,7 +287,7 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
287 add_debug_source_node(g, node);287 add_debug_source_node(g, node);
288 LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, "");288 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
292 LLVMValueRef params[] = {292 LLVMValueRef params[] = {
293 dest_ptr_casted, // dest pointer293 dest_ptr_casted, // dest pointer
...@@ -301,6 +301,7 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {...@@ -301,6 +301,7 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
301 return nullptr;301 return nullptr;
302 }302 }
303 case BuiltinFnIdSizeof:303 case BuiltinFnIdSizeof:
304 case BuiltinFnIdAlignof:
304 case BuiltinFnIdMinValue:305 case BuiltinFnIdMinValue:
305 case BuiltinFnIdMaxValue:306 case BuiltinFnIdMaxValue:
306 case BuiltinFnIdMemberCount:307 case BuiltinFnIdMemberCount:
...@@ -359,9 +360,21 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT...@@ -359,9 +360,21 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT
359 TypeTableEntry *wanted_type, LLVMValueRef expr_val)360 TypeTableEntry *wanted_type, LLVMValueRef expr_val)
360{361{
361 assert(actual_type->id == wanted_type->id);362 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) {
363 return expr_val;376 return expr_val;
364 } else if (actual_type->size_in_bits < wanted_type->size_in_bits) {377 } else if (actual_bits < wanted_bits) {
365 if (actual_type->id == TypeTableEntryIdFloat) {378 if (actual_type->id == TypeTableEntryIdFloat) {
366 add_debug_source_node(g, source_node);379 add_debug_source_node(g, source_node);
367 return LLVMBuildFPExt(g->builder, expr_val, wanted_type->type_ref, "");380 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...@@ -376,7 +389,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT
376 } else {389 } else {
377 zig_unreachable();390 zig_unreachable();
378 }391 }
379 } else if (actual_type->size_in_bits > wanted_type->size_in_bits) {392 } else if (actual_bits > wanted_bits) {
380 if (actual_type->id == TypeTableEntryIdFloat) {393 if (actual_type->id == TypeTableEntryIdFloat) {
381 add_debug_source_node(g, source_node);394 add_debug_source_node(g, source_node);
382 return LLVMBuildFPTrunc(g->builder, expr_val, wanted_type->type_ref, "");395 return LLVMBuildFPTrunc(g->builder, expr_val, wanted_type->type_ref, "");
...@@ -410,7 +423,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {...@@ -410,7 +423,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
410 return expr_val;423 return expr_val;
411 case CastOpErrToInt:424 case CastOpErrToInt:
412 assert(actual_type->id == TypeTableEntryIdErrorUnion);425 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)) {
414 return gen_widen_or_shorten(g, node, g->err_tag_type, wanted_type, expr_val);427 return gen_widen_or_shorten(g, node, g->err_tag_type, wanted_type, expr_val);
415 } else {428 } else {
416 zig_panic("TODO");429 zig_panic("TODO");
...@@ -446,7 +459,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {...@@ -446,7 +459,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
446 TypeTableEntry *child_type = wanted_type->data.error.child_type;459 TypeTableEntry *child_type = wanted_type->data.error.child_type;
447 LLVMValueRef ok_err_val = LLVMConstNull(g->err_tag_type->type_ref);460 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)) {
450 return ok_err_val;463 return ok_err_val;
451 } else {464 } else {
452 assert(cast_expr->tmp_ptr);465 assert(cast_expr->tmp_ptr);
...@@ -466,7 +479,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {...@@ -466,7 +479,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
466 }479 }
467 case CastOpPureErrorWrap:480 case CastOpPureErrorWrap:
468 assert(wanted_type->id == TypeTableEntryIdErrorUnion);481 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)) {
470 return expr_val;483 return expr_val;
471 } else {484 } else {
472 zig_panic("TODO");485 zig_panic("TODO");
...@@ -607,7 +620,7 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {...@@ -607,7 +620,7 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {
607 AstNode *expr_node = node->data.fn_call_expr.params.at(i);620 AstNode *expr_node = node->data.fn_call_expr.params.at(i);
608 LLVMValueRef param_value = gen_expr(g, expr_node);621 LLVMValueRef param_value = gen_expr(g, expr_node);
609 TypeTableEntry *param_type = get_expr_type(expr_node);622 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)) {
611 gen_param_values[gen_param_index] = param_value;624 gen_param_values[gen_param_index] = param_value;
612 gen_param_index += 1;625 gen_param_index += 1;
613 }626 }
...@@ -621,7 +634,7 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {...@@ -621,7 +634,7 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {
621 return LLVMBuildUnreachable(g->builder);634 return LLVMBuildUnreachable(g->builder);
622 } else if (first_arg_ret) {635 } else if (first_arg_ret) {
623 return node->data.fn_call_expr.tmp_ptr;636 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)) {
625 return nullptr;638 return nullptr;
626 } else {639 } else {
627 return result;640 return result;
...@@ -653,7 +666,7 @@ static LLVMValueRef gen_array_elem_ptr(CodeGen *g, AstNode *source_node, LLVMVal...@@ -653,7 +666,7 @@ static LLVMValueRef gen_array_elem_ptr(CodeGen *g, AstNode *source_node, LLVMVal
653{666{
654 assert(subscript_value);667 assert(subscript_value);
655668
656 if (array_type->size_in_bits == 0) {669 if (!type_has_bits(array_type)) {
657 return nullptr;670 return nullptr;
658 }671 }
659672
...@@ -978,7 +991,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {...@@ -978,7 +991,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
978 case PrefixOpDereference:991 case PrefixOpDereference:
979 {992 {
980 LLVMValueRef expr = gen_expr(g, expr_node);993 LLVMValueRef expr = gen_expr(g, expr_node);
981 if (expr_type->size_in_bits == 0) {994 if (!type_has_bits(expr_type)) {
982 return nullptr;995 return nullptr;
983 } else {996 } else {
984 add_debug_source_node(g, node);997 add_debug_source_node(g, node);
...@@ -1002,7 +1015,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {...@@ -1002,7 +1015,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
10021015
1003 if (g->build_type != CodeGenBuildTypeRelease) {1016 if (g->build_type != CodeGenBuildTypeRelease) {
1004 LLVMValueRef err_val;1017 LLVMValueRef err_val;
1005 if (child_type->size_in_bits > 0) {1018 if (type_has_bits(child_type)) {
1006 add_debug_source_node(g, node);1019 add_debug_source_node(g, node);
1007 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 0, "");1020 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 0, "");
1008 err_val = LLVMBuildLoad(g->builder, err_val_ptr, "");1021 err_val = LLVMBuildLoad(g->builder, err_val_ptr, "");
...@@ -1022,7 +1035,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {...@@ -1022,7 +1035,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
1022 LLVMPositionBuilderAtEnd(g->builder, ok_block);1035 LLVMPositionBuilderAtEnd(g->builder, ok_block);
1023 }1036 }
10241037
1025 if (child_type->size_in_bits > 0) {1038 if (type_has_bits(child_type)) {
1026 LLVMValueRef child_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, "");1039 LLVMValueRef child_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, "");
1027 if (handle_is_ptr(child_type)) {1040 if (handle_is_ptr(child_type)) {
1028 return child_val_ptr;1041 return child_val_ptr;
...@@ -1337,11 +1350,15 @@ static LLVMValueRef gen_struct_memcpy(CodeGen *g, AstNode *source_node, LLVMValu...@@ -1337,11 +1350,15 @@ static LLVMValueRef gen_struct_memcpy(CodeGen *g, AstNode *source_node, LLVMValu
1337 LLVMValueRef src_ptr = LLVMBuildBitCast(g->builder, src, ptr_u8, "");1350 LLVMValueRef src_ptr = LLVMBuildBitCast(g->builder, src, ptr_u8, "");
1338 LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, dest, ptr_u8, "");1351 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
1340 LLVMValueRef params[] = {1357 LLVMValueRef params[] = {
1341 dest_ptr, // dest pointer1358 dest_ptr, // dest pointer
1342 src_ptr, // source pointer1359 src_ptr, // source pointer
1343 LLVMConstInt(LLVMIntType(g->pointer_size_bytes * 8), type_entry->size_in_bits / 8, false), // byte count1360 LLVMConstInt(isize->type_ref, size_bytes, false),
1344 LLVMConstInt(LLVMInt32Type(), type_entry->align_in_bits / 8, false), // align in bytes1361 LLVMConstInt(LLVMInt32Type(), align_bytes, false),
1345 LLVMConstNull(LLVMInt1Type()), // is volatile1362 LLVMConstNull(LLVMInt1Type()), // is volatile
1346 };1363 };
13471364
...@@ -1384,7 +1401,7 @@ static LLVMValueRef gen_assign_expr(CodeGen *g, AstNode *node) {...@@ -1384,7 +1401,7 @@ static LLVMValueRef gen_assign_expr(CodeGen *g, AstNode *node) {
13841401
1385 LLVMValueRef value = gen_expr(g, node->data.bin_op_expr.op2);1402 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)) {
1388 return nullptr;1405 return nullptr;
1389 }1406 }
13901407
...@@ -1546,7 +1563,7 @@ static LLVMValueRef gen_unwrap_err_expr(CodeGen *g, AstNode *node) {...@@ -1546,7 +1563,7 @@ static LLVMValueRef gen_unwrap_err_expr(CodeGen *g, AstNode *node) {
1546 LLVMBasicBlockRef err_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapErrError");1563 LLVMBasicBlockRef err_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapErrError");
1547 LLVMBasicBlockRef end_block;1564 LLVMBasicBlockRef end_block;
1548 bool err_reachable = op2_type->id != TypeTableEntryIdUnreachable;1565 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);
1550 if (have_end_block) {1567 if (have_end_block) {
1551 end_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapErrEnd");1568 end_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapErrEnd");
1552 }1569 }
...@@ -1566,7 +1583,7 @@ static LLVMValueRef gen_unwrap_err_expr(CodeGen *g, AstNode *node) {...@@ -1566,7 +1583,7 @@ static LLVMValueRef gen_unwrap_err_expr(CodeGen *g, AstNode *node) {
1566 }1583 }
15671584
1568 LLVMPositionBuilderAtEnd(g->builder, ok_block);1585 LLVMPositionBuilderAtEnd(g->builder, ok_block);
1569 if (child_type->size_in_bits == 0) {1586 if (!type_has_bits(child_type)) {
1570 return nullptr;1587 return nullptr;
1571 }1588 }
1572 LLVMValueRef child_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, "");1589 LLVMValueRef child_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, "");
...@@ -1624,7 +1641,7 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) {...@@ -1624,7 +1641,7 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) {
16241641
1625 add_debug_source_node(g, node);1642 add_debug_source_node(g, node);
1626 LLVMValueRef err_val;1643 LLVMValueRef err_val;
1627 if (child_type->size_in_bits > 0) {1644 if (type_has_bits(child_type)) {
1628 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, value, 0, "");1645 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, value, 0, "");
1629 err_val = LLVMBuildLoad(g->builder, err_val_ptr, "");1646 err_val = LLVMBuildLoad(g->builder, err_val_ptr, "");
1630 } else {1647 } else {
...@@ -1639,7 +1656,7 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) {...@@ -1639,7 +1656,7 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) {
1639 if (return_type->id == TypeTableEntryIdPureError) {1656 if (return_type->id == TypeTableEntryIdPureError) {
1640 gen_return(g, node, err_val);1657 gen_return(g, node, err_val);
1641 } else if (return_type->id == TypeTableEntryIdErrorUnion) {1658 } 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)) {
1643 assert(g->cur_ret_ptr);1660 assert(g->cur_ret_ptr);
16441661
1645 add_debug_source_node(g, node);1662 add_debug_source_node(g, node);
...@@ -1654,7 +1671,7 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) {...@@ -1654,7 +1671,7 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) {
1654 }1671 }
16551672
1656 LLVMPositionBuilderAtEnd(g->builder, continue_block);1673 LLVMPositionBuilderAtEnd(g->builder, continue_block);
1657 if (child_type->size_in_bits > 0) {1674 if (type_has_bits(child_type)) {
1658 add_debug_source_node(g, node);1675 add_debug_source_node(g, node);
1659 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, value, 1, "");1676 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, value, 1, "");
1660 if (handle_is_ptr(child_type)) {1677 if (handle_is_ptr(child_type)) {
...@@ -2164,7 +2181,7 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa...@@ -2164,7 +2181,7 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa
2164 *init_value = gen_expr(g, var_decl->expr);2181 *init_value = gen_expr(g, var_decl->expr);
2165 *expr_type = get_expr_type(var_decl->expr);2182 *expr_type = get_expr_type(var_decl->expr);
2166 }2183 }
2167 if (variable->type->size_in_bits == 0) {2184 if (!type_has_bits(variable->type)) {
2168 return nullptr;2185 return nullptr;
2169 }2186 }
21702187
...@@ -2225,15 +2242,17 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa...@@ -2225,15 +2242,17 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa
2225 }2242 }
2226 }2243 }
2227 if (!ignore_uninit && g->build_type != CodeGenBuildTypeRelease) {2244 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
2228 // memset uninitialized memory to 0xa2249 // memset uninitialized memory to 0xa
2229 add_debug_source_node(g, source_node);2250 add_debug_source_node(g, source_node);
2230 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);2251 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
2231 LLVMValueRef fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false);2252 LLVMValueRef fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false);
2232 LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, variable->value_ref, ptr_u8, "");2253 LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, variable->value_ref, ptr_u8, "");
2233 LLVMValueRef byte_count = LLVMConstInt(LLVMIntType(g->pointer_size_bytes * 8),2254 LLVMValueRef byte_count = LLVMConstInt(isize->type_ref, size_bytes, false);
2234 variable->type->size_in_bits / 8, false);2255 LLVMValueRef align_in_bytes = LLVMConstInt(LLVMInt32Type(), align_bytes, false);
2235 LLVMValueRef align_in_bytes = LLVMConstInt(LLVMInt32Type(),
2236 variable->type->align_in_bits / 8, false);
2237 LLVMValueRef params[] = {2256 LLVMValueRef params[] = {
2238 dest_ptr,2257 dest_ptr,
2239 fill_char,2258 fill_char,
...@@ -2273,7 +2292,7 @@ static LLVMValueRef gen_symbol(CodeGen *g, AstNode *node) {...@@ -2273,7 +2292,7 @@ static LLVMValueRef gen_symbol(CodeGen *g, AstNode *node) {
2273 assert(node->type == NodeTypeSymbol);2292 assert(node->type == NodeTypeSymbol);
2274 VariableTableEntry *variable = node->data.symbol_expr.variable;2293 VariableTableEntry *variable = node->data.symbol_expr.variable;
2275 if (variable) {2294 if (variable) {
2276 if (variable->type->size_in_bits == 0) {2295 if (!type_has_bits(variable->type)) {
2277 return nullptr;2296 return nullptr;
2278 } else if (variable->is_ptr) {2297 } else if (variable->is_ptr) {
2279 assert(variable->value_ref);2298 assert(variable->value_ref);
...@@ -2364,7 +2383,7 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) {...@@ -2364,7 +2383,7 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) {
2364static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {2383static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
2365 Expr *expr = get_resolved_expr(node);2384 Expr *expr = get_resolved_expr(node);
2366 if (expr->const_val.ok) {2385 if (expr->const_val.ok) {
2367 if (expr->type_entry->size_in_bits == 0) {2386 if (!type_has_bits(expr->type_entry)) {
2368 return nullptr;2387 return nullptr;
2369 } else {2388 } else {
2370 assert(expr->const_llvm_val);2389 assert(expr->const_llvm_val);
...@@ -2600,7 +2619,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE...@@ -2600,7 +2619,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
2600 case TypeTableEntryIdErrorUnion:2619 case TypeTableEntryIdErrorUnion:
2601 {2620 {
2602 TypeTableEntry *child_type = type_entry->data.error.child_type;2621 TypeTableEntry *child_type = type_entry->data.error.child_type;
2603 if (child_type->size_in_bits == 0) {2622 if (!type_has_bits(child_type)) {
2604 uint64_t value = const_val->data.x_err.err ? const_val->data.x_err.err->value : 0;2623 uint64_t value = const_val->data.x_err.err ? const_val->data.x_err.err->value : 0;
2605 return LLVMConstInt(g->err_tag_type->type_ref, value, false);2624 return LLVMConstInt(g->err_tag_type->type_ref, value, false);
2606 } else {2625 } else {
...@@ -2683,7 +2702,7 @@ static void do_code_gen(CodeGen *g) {...@@ -2683,7 +2702,7 @@ static void do_code_gen(CodeGen *g) {
26832702
2684 if (var->type->id == TypeTableEntryIdNumLitFloat ||2703 if (var->type->id == TypeTableEntryIdNumLitFloat ||
2685 var->type->id == TypeTableEntryIdNumLitInt ||2704 var->type->id == TypeTableEntryIdNumLitInt ||
2686 var->type->size_in_bits == 0)2705 !type_has_bits(var->type))
2687 {2706 {
2688 continue;2707 continue;
2689 }2708 }
...@@ -2820,7 +2839,7 @@ static void do_code_gen(CodeGen *g) {...@@ -2820,7 +2839,7 @@ static void do_code_gen(CodeGen *g) {
2820 for (int var_i = 0; var_i < block_context->variable_list.length; var_i += 1) {2839 for (int var_i = 0; var_i < block_context->variable_list.length; var_i += 1) {
2821 VariableTableEntry *var = block_context->variable_list.at(var_i);2840 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)) {
2824 continue;2843 continue;
2825 }2844 }
28262845
...@@ -2839,7 +2858,8 @@ static void do_code_gen(CodeGen *g) {...@@ -2839,7 +2858,8 @@ static void do_code_gen(CodeGen *g) {
28392858
2840 add_debug_source_node(g, var->decl_node);2859 add_debug_source_node(g, var->decl_node);
2841 var->value_ref = LLVMBuildAlloca(g->builder, var->type->type_ref, buf_ptr(&var->name));2860 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);
2843 }2863 }
28442864
2845 var->di_loc_var = LLVMZigCreateLocalVariable(g->dbuilder, tag,2865 var->di_loc_var = LLVMZigCreateLocalVariable(g->dbuilder, tag,
...@@ -2953,16 +2973,19 @@ static void define_builtin_types(CodeGen *g) {...@@ -2953,16 +2973,19 @@ static void define_builtin_types(CodeGen *g) {
2953 // if this type is anywhere in the AST, we should never hit codegen.2973 // if this type is anywhere in the AST, we should never hit codegen.
2954 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInvalid);2974 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInvalid);
2955 buf_init_from_str(&entry->name, "(invalid)");2975 buf_init_from_str(&entry->name, "(invalid)");
2976 entry->zero_bits = true;
2956 g->builtin_types.entry_invalid = entry;2977 g->builtin_types.entry_invalid = entry;
2957 }2978 }
2958 {2979 {
2959 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitFloat);2980 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitFloat);
2960 buf_init_from_str(&entry->name, "(float literal)");2981 buf_init_from_str(&entry->name, "(float literal)");
2982 entry->zero_bits = true;
2961 g->builtin_types.entry_num_lit_float = entry;2983 g->builtin_types.entry_num_lit_float = entry;
2962 }2984 }
2963 {2985 {
2964 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitInt);2986 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitInt);
2965 buf_init_from_str(&entry->name, "(integer literal)");2987 buf_init_from_str(&entry->name, "(integer literal)");
2988 entry->zero_bits = true;
2966 g->builtin_types.entry_num_lit_int = entry;2989 g->builtin_types.entry_num_lit_int = entry;
2967 }2990 }
2968 {2991 {
...@@ -2982,12 +3005,13 @@ static void define_builtin_types(CodeGen *g) {...@@ -2982,12 +3005,13 @@ static void define_builtin_types(CodeGen *g) {
2982 buf_resize(&entry->name, 0);3005 buf_resize(&entry->name, 0);
2983 buf_appendf(&entry->name, "%c%d", u_or_i, size_in_bits);3006 buf_appendf(&entry->name, "%c%d", u_or_i, size_in_bits);
29843007
2985 entry->size_in_bits = size_in_bits;3008 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref);
2986 entry->align_in_bits = size_in_bits;3009 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
2987 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),3010 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,
2989 is_signed ? LLVMZigEncoding_DW_ATE_signed() : LLVMZigEncoding_DW_ATE_unsigned());3012 is_signed ? LLVMZigEncoding_DW_ATE_signed() : LLVMZigEncoding_DW_ATE_unsigned());
2990 entry->data.integral.is_signed = is_signed;3013 entry->data.integral.is_signed = is_signed;
3014 entry->data.integral.bit_count = size_in_bits;
2991 g->primitive_type_table.put(&entry->name, entry);3015 g->primitive_type_table.put(&entry->name, entry);
29923016
2993 get_int_type_ptr(g, is_signed, size_in_bits)[0] = entry;3017 get_int_type_ptr(g, is_signed, size_in_bits)[0] = entry;
...@@ -3010,13 +3034,14 @@ static void define_builtin_types(CodeGen *g) {...@@ -3010,13 +3034,14 @@ static void define_builtin_types(CodeGen *g) {
30103034
3011 buf_init_from_str(&entry->name, info->name);3035 buf_init_from_str(&entry->name, info->name);
30123036
3013 entry->size_in_bits = size_in_bits;3037 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref);
3014 entry->align_in_bits = size_in_bits;3038 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
3015
3016 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),3039 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,
3018 is_signed ? LLVMZigEncoding_DW_ATE_signed() : LLVMZigEncoding_DW_ATE_unsigned());3042 is_signed ? LLVMZigEncoding_DW_ATE_signed() : LLVMZigEncoding_DW_ATE_unsigned());
3019 entry->data.integral.is_signed = is_signed;3043 entry->data.integral.is_signed = is_signed;
3044 entry->data.integral.bit_count = size_in_bits;
3020 g->primitive_type_table.put(&entry->name, entry);3045 g->primitive_type_table.put(&entry->name, entry);
30213046
3022 get_c_int_type_ptr(g, info->id)[0] = entry;3047 get_c_int_type_ptr(g, info->id)[0] = entry;
...@@ -3026,10 +3051,11 @@ static void define_builtin_types(CodeGen *g) {...@@ -3026,10 +3051,11 @@ static void define_builtin_types(CodeGen *g) {
3026 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdBool);3051 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdBool);
3027 entry->type_ref = LLVMInt1Type();3052 entry->type_ref = LLVMInt1Type();
3028 buf_init_from_str(&entry->name, "bool");3053 buf_init_from_str(&entry->name, "bool");
3029 entry->size_in_bits = 8;3054 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref);
3030 entry->align_in_bits = 8;3055 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
3031 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),3056 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,
3033 LLVMZigEncoding_DW_ATE_unsigned());3059 LLVMZigEncoding_DW_ATE_unsigned());
3034 g->builtin_types.entry_bool = entry;3060 g->builtin_types.entry_bool = entry;
3035 g->primitive_type_table.put(&entry->name, entry);3061 g->primitive_type_table.put(&entry->name, entry);
...@@ -3038,12 +3064,14 @@ static void define_builtin_types(CodeGen *g) {...@@ -3038,12 +3064,14 @@ static void define_builtin_types(CodeGen *g) {
3038 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);3064 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
3039 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);3065 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);
3040 buf_init_from_str(&entry->name, "isize");3066 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;
3043 entry->data.integral.is_signed = true;3067 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);
3045 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),3072 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,
3047 LLVMZigEncoding_DW_ATE_signed());3075 LLVMZigEncoding_DW_ATE_signed());
3048 g->builtin_types.entry_isize = entry;3076 g->builtin_types.entry_isize = entry;
3049 g->primitive_type_table.put(&entry->name, entry);3077 g->primitive_type_table.put(&entry->name, entry);
...@@ -3052,12 +3080,14 @@ static void define_builtin_types(CodeGen *g) {...@@ -3052,12 +3080,14 @@ static void define_builtin_types(CodeGen *g) {
3052 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);3080 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
3053 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);3081 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);
3054 buf_init_from_str(&entry->name, "usize");3082 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;
3057 entry->data.integral.is_signed = false;3083 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);
3059 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),3088 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,
3061 LLVMZigEncoding_DW_ATE_unsigned());3091 LLVMZigEncoding_DW_ATE_unsigned());
3062 g->builtin_types.entry_usize = entry;3092 g->builtin_types.entry_usize = entry;
3063 g->primitive_type_table.put(&entry->name, entry);3093 g->primitive_type_table.put(&entry->name, entry);
...@@ -3066,10 +3096,13 @@ static void define_builtin_types(CodeGen *g) {...@@ -3066,10 +3096,13 @@ static void define_builtin_types(CodeGen *g) {
3066 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);3096 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
3067 entry->type_ref = LLVMFloatType();3097 entry->type_ref = LLVMFloatType();
3068 buf_init_from_str(&entry->name, "f32");3098 buf_init_from_str(&entry->name, "f32");
3069 entry->size_in_bits = 32;3099 entry->data.floating.bit_count = 32;
3070 entry->align_in_bits = 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);
3071 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),3103 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,
3073 LLVMZigEncoding_DW_ATE_float());3106 LLVMZigEncoding_DW_ATE_float());
3074 g->builtin_types.entry_f32 = entry;3107 g->builtin_types.entry_f32 = entry;
3075 g->primitive_type_table.put(&entry->name, entry);3108 g->primitive_type_table.put(&entry->name, entry);
...@@ -3078,10 +3111,13 @@ static void define_builtin_types(CodeGen *g) {...@@ -3078,10 +3111,13 @@ static void define_builtin_types(CodeGen *g) {
3078 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);3111 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
3079 entry->type_ref = LLVMDoubleType();3112 entry->type_ref = LLVMDoubleType();
3080 buf_init_from_str(&entry->name, "f64");3113 buf_init_from_str(&entry->name, "f64");
3081 entry->size_in_bits = 64;3114 entry->data.floating.bit_count = 64;
3082 entry->align_in_bits = 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);
3083 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),3118 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,
3085 LLVMZigEncoding_DW_ATE_float());3121 LLVMZigEncoding_DW_ATE_float());
3086 g->builtin_types.entry_f64 = entry;3122 g->builtin_types.entry_f64 = entry;
3087 g->primitive_type_table.put(&entry->name, entry);3123 g->primitive_type_table.put(&entry->name, entry);
...@@ -3090,10 +3126,13 @@ static void define_builtin_types(CodeGen *g) {...@@ -3090,10 +3126,13 @@ static void define_builtin_types(CodeGen *g) {
3090 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);3126 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
3091 entry->type_ref = LLVMX86FP80Type();3127 entry->type_ref = LLVMX86FP80Type();
3092 buf_init_from_str(&entry->name, "c_long_double");3128 buf_init_from_str(&entry->name, "c_long_double");
3093 entry->size_in_bits = 128;3129 entry->data.floating.bit_count = 80;
3094 entry->align_in_bits = 128;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);
3095 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),3133 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,
3097 LLVMZigEncoding_DW_ATE_float());3136 LLVMZigEncoding_DW_ATE_float());
3098 g->builtin_types.entry_c_long_double = entry;3137 g->builtin_types.entry_c_long_double = entry;
3099 g->primitive_type_table.put(&entry->name, entry);3138 g->primitive_type_table.put(&entry->name, entry);
...@@ -3101,9 +3140,11 @@ static void define_builtin_types(CodeGen *g) {...@@ -3101,9 +3140,11 @@ static void define_builtin_types(CodeGen *g) {
3101 {3140 {
3102 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);3141 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);
3103 entry->type_ref = LLVMVoidType();3142 entry->type_ref = LLVMVoidType();
3143 entry->zero_bits = true;
3104 buf_init_from_str(&entry->name, "void");3144 buf_init_from_str(&entry->name, "void");
3105 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),3145 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),
3106 entry->size_in_bits, entry->align_in_bits,3146 0,
3147 0,
3107 LLVMZigEncoding_DW_ATE_unsigned());3148 LLVMZigEncoding_DW_ATE_unsigned());
3108 g->builtin_types.entry_void = entry;3149 g->builtin_types.entry_void = entry;
3109 g->primitive_type_table.put(&entry->name, entry);3150 g->primitive_type_table.put(&entry->name, entry);
...@@ -3111,6 +3152,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3111,6 +3152,7 @@ static void define_builtin_types(CodeGen *g) {
3111 {3152 {
3112 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUnreachable);3153 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUnreachable);
3113 entry->type_ref = LLVMVoidType();3154 entry->type_ref = LLVMVoidType();
3155 entry->zero_bits = true;
3114 buf_init_from_str(&entry->name, "unreachable");3156 buf_init_from_str(&entry->name, "unreachable");
3115 entry->di_type = g->builtin_types.entry_void->di_type;3157 entry->di_type = g->builtin_types.entry_void->di_type;
3116 g->builtin_types.entry_unreachable = entry;3158 g->builtin_types.entry_unreachable = entry;
...@@ -3119,6 +3161,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3119,6 +3161,7 @@ static void define_builtin_types(CodeGen *g) {
3119 {3161 {
3120 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMetaType);3162 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMetaType);
3121 buf_init_from_str(&entry->name, "type");3163 buf_init_from_str(&entry->name, "type");
3164 entry->zero_bits = true;
3122 g->builtin_types.entry_type = entry;3165 g->builtin_types.entry_type = entry;
3123 g->primitive_type_table.put(&entry->name, entry);3166 g->primitive_type_table.put(&entry->name, entry);
3124 }3167 }
...@@ -3212,6 +3255,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -3212,6 +3255,7 @@ static void define_builtin_fns(CodeGen *g) {
3212 g->memset_fn_val = builtin_fn->fn_val;3255 g->memset_fn_val = builtin_fn->fn_val;
3213 }3256 }
3214 create_builtin_fn_with_arg_count(g, BuiltinFnIdSizeof, "sizeof", 1);3257 create_builtin_fn_with_arg_count(g, BuiltinFnIdSizeof, "sizeof", 1);
3258 create_builtin_fn_with_arg_count(g, BuiltinFnIdAlignof, "alignof", 1);
3215 create_builtin_fn_with_arg_count(g, BuiltinFnIdMaxValue, "max_value", 1);3259 create_builtin_fn_with_arg_count(g, BuiltinFnIdMaxValue, "max_value", 1);
3216 create_builtin_fn_with_arg_count(g, BuiltinFnIdMinValue, "min_value", 1);3260 create_builtin_fn_with_arg_count(g, BuiltinFnIdMinValue, "min_value", 1);
3217 create_builtin_fn_with_arg_count(g, BuiltinFnIdMemberCount, "member_count", 1);3261 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) {...@@ -740,8 +740,6 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
740 enum_type->data.enumeration.complete = true;740 enum_type->data.enumeration.complete = true;
741741
742 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(c->codegen, field_count);742 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;
745 enum_type->data.enumeration.tag_type = tag_type_entry;743 enum_type->data.enumeration.tag_type = tag_type_entry;
746744
747 c->enum_type_table.put(bare_name, enum_type);745 c->enum_type_table.put(bare_name, enum_type);
...@@ -795,11 +793,14 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {...@@ -795,11 +793,14 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
795793
796 // create debug type for tag794 // create debug type for tag
797 unsigned line = c->source_node ? (c->source_node->line + 1) : 0;795 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);
798 LLVMZigDIType *tag_di_type = LLVMZigCreateDebugEnumerationType(c->codegen->dbuilder,798 LLVMZigDIType *tag_di_type = LLVMZigCreateDebugEnumerationType(c->codegen->dbuilder,
799 LLVMZigFileToScope(c->import->di_file), buf_ptr(bare_name),799 LLVMZigFileToScope(c->import->di_file), buf_ptr(bare_name),
800 c->import->di_file, line,800 c->import->di_file, line,
801 tag_type_entry->size_in_bits, tag_type_entry->align_in_bits, di_enumerators, field_count,801 debug_size_in_bits,
802 tag_type_entry->di_type, "");802 debug_align_in_bits,
803 di_enumerators, field_count, tag_type_entry->di_type, "");
803804
804 LLVMZigReplaceTemporary(c->codegen->dbuilder, enum_type->di_type, tag_di_type);805 LLVMZigReplaceTemporary(c->codegen->dbuilder, enum_type->di_type, tag_di_type);
805 enum_type->di_type = tag_di_type;806 enum_type->di_type = tag_di_type;
...@@ -894,10 +895,6 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_...@@ -894,10 +895,6 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
894 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);895 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);
895 LLVMZigDIType **di_element_types = allocate<LLVMZigDIType*>(field_count);896 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
901 uint32_t i = 0;898 uint32_t i = 0;
902 for (auto it = record_def->field_begin(),899 for (auto it = record_def->field_begin(),
903 it_end = record_def->field_end();900 it_end = record_def->field_end();
...@@ -909,30 +906,29 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_...@@ -909,30 +906,29 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
909 type_struct_field->name = buf_create_from_str(decl_name(field_decl));906 type_struct_field->name = buf_create_from_str(decl_name(field_decl));
910 type_struct_field->src_index = i;907 type_struct_field->src_index = i;
911 type_struct_field->gen_index = i;908 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) {
915 emit_warning(c, field_decl, "struct %s demoted to typedef - unresolved type\n", buf_ptr(bare_name));913 emit_warning(c, field_decl, "struct %s demoted to typedef - unresolved type\n", buf_ptr(bare_name));
916 return struct_type;914 return struct_type;
917 }915 }
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);
919 di_element_types[i] = LLVMZigCreateDebugMemberType(c->codegen->dbuilder,920 di_element_types[i] = LLVMZigCreateDebugMemberType(c->codegen->dbuilder,
920 LLVMZigTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name),921 LLVMZigTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name),
921 c->import->di_file, line + 1,922 c->import->di_file, line + 1,
922 type_struct_field->type_entry->size_in_bits,923 debug_size_in_bits,
923 type_struct_field->type_entry->align_in_bits,924 debug_align_in_bits,
924 offset_in_bits, 0, type_struct_field->type_entry->di_type);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;
927 assert(di_element_types[i]);929 assert(di_element_types[i]);
928 assert(element_types[i]);930 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
936 }932 }
937 struct_type->data.structure.embedded_in_current = false;933 struct_type->data.structure.embedded_in_current = false;
938934
...@@ -941,13 +937,14 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_...@@ -941,13 +937,14 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
941937
942 LLVMStructSetBody(struct_type->type_ref, element_types, field_count, false);938 LLVMStructSetBody(struct_type->type_ref, element_types, field_count, false);
943939
944 struct_type->align_in_bits = first_field_align_in_bits;940 uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(c->codegen->target_data_ref, struct_type->type_ref);
945 struct_type->size_in_bits = total_size_in_bits;941 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, struct_type->type_ref);
946
947 LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(c->codegen->dbuilder,942 LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(c->codegen->dbuilder,
948 LLVMZigFileToScope(c->import->di_file),943 LLVMZigFileToScope(c->import->di_file),
949 buf_ptr(full_type_name),944 buf_ptr(full_type_name), c->import->di_file, line + 1,
950 c->import->di_file, line + 1, struct_type->size_in_bits, struct_type->align_in_bits, 0,945 debug_size_in_bits,
946 debug_align_in_bits,
947 0,
951 nullptr, di_element_types, field_count, 0, nullptr, "");948 nullptr, di_element_types, field_count, 0, nullptr, "");
952949
953 LLVMZigReplaceTemporary(c->codegen->dbuilder, struct_type->di_type, replacement_di_type);950 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 {...@@ -379,10 +379,10 @@ pub fn main(args: [][]u8) -> %void {
379 array[0] = void{};379 array[0] = void{};
380 array[1] = array[2];380 array[1] = array[2];
381 if (@sizeof(@typeof(array)) != 0) {381 if (@sizeof(@typeof(array)) != 0) {
382 %%stdout.printf("BAD\n");382 %%stdout.printf("BAD sizeof\n");
383 }383 }
384 if (array.len != 4) {384 if (array.len != 4) {
385 %%stdout.printf("BAD\n");385 %%stdout.printf("BAD len\n");
386 }386 }
387 %%stdout.printf("OK\n");387 %%stdout.printf("OK\n");
388}388}
...@@ -1075,22 +1075,22 @@ pub fn main(args: [][]u8) -> %void {...@@ -1075,22 +1075,22 @@ pub fn main(args: [][]u8) -> %void {
1075 const bar = Bar.B;1075 const bar = Bar.B;
10761076
1077 if (bar != Bar.B) {1077 if (bar != Bar.B) {
1078 %%stdout.printf("BAD\n");1078 %%stdout.printf("BAD 1\n");
1079 }1079 }
10801080
1081 if (@member_count(Foo) != 3) {1081 if (@member_count(Foo) != 3) {
1082 %%stdout.printf("BAD\n");1082 %%stdout.printf("BAD 2\n");
1083 }1083 }
10841084
1085 if (@member_count(Bar) != 4) {1085 if (@member_count(Bar) != 4) {
1086 %%stdout.printf("BAD\n");1086 %%stdout.printf("BAD 3\n");
1087 }1087 }
10881088
1089 if (@sizeof(Foo) != 17) {1089 if (@sizeof(Foo) != 24) {
1090 %%stdout.printf("BAD\n");1090 %%stdout.printf("BAD 4\n");
1091 }1091 }
1092 if (@sizeof(Bar) != 1) {1092 if (@sizeof(Bar) != 1) {
1093 %%stdout.printf("BAD\n");1093 %%stdout.printf("BAD 5\n");
1094 }1094 }
10951095
1096 %%stdout.printf("OK\n");1096 %%stdout.printf("OK\n");