| ... | ... | @@ -200,27 +200,21 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool |
| 200 | 200 | TypeTableEntry *canon_child_type = get_underlying_type(child_type); |
| 201 | 201 | assert(canon_child_type->id != TypeTableEntryIdInvalid); |
| 202 | 202 | |
| 203 | | bool zero_bits; |
| 204 | | if (canon_child_type->size_in_bits == 0) { |
| 205 | | if (canon_child_type->id == TypeTableEntryIdStruct) { |
| 206 | | zero_bits = canon_child_type->data.structure.complete; |
| 207 | | } else if (canon_child_type->id == TypeTableEntryIdEnum) { |
| 208 | | zero_bits = canon_child_type->data.enumeration.complete; |
| 209 | | } else { |
| 210 | | zero_bits = true; |
| 211 | | } |
| 203 | |
| 204 | if (type_is_complete(canon_child_type)) { |
| 205 | entry->zero_bits = !type_has_bits(canon_child_type); |
| 212 | 206 | } else { |
| 213 | | zero_bits = false; |
| 207 | entry->zero_bits = false; |
| 214 | 208 | } |
| 215 | 209 | |
| 216 | | if (!zero_bits) { |
| 210 | if (!entry->zero_bits) { |
| 217 | 211 | entry->type_ref = LLVMPointerType(child_type->type_ref, 0); |
| 218 | 212 | |
| 219 | | entry->size_in_bits = g->pointer_size_bytes * 8; |
| 220 | | entry->align_in_bits = g->pointer_size_bytes * 8; |
| 213 | uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref); |
| 214 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref); |
| 221 | 215 | assert(child_type->di_type); |
| 222 | 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 | } |
| 225 | 219 | |
| 226 | 220 | entry->data.pointer.child_type = child_type; |
| ... | ... | @@ -249,8 +243,6 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) { |
| 249 | 243 | // this is an optimization but also is necessary for calling C |
| 250 | 244 | // functions where all pointers are maybe pointers |
| 251 | 245 | // 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 | 246 | entry->type_ref = child_type->type_ref; |
| 255 | 247 | entry->di_type = child_type->di_type; |
| 256 | 248 | } else { |
| ... | ... | @@ -260,8 +252,6 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) { |
| 260 | 252 | LLVMInt1Type(), |
| 261 | 253 | }; |
| 262 | 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; |
| 265 | 255 | |
| 266 | 256 | |
| 267 | 257 | LLVMZigDIScope *compile_unit_scope = LLVMZigCompileUnitToScope(g->compile_unit); |
| ... | ... | @@ -271,18 +261,36 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) { |
| 271 | 261 | LLVMZigTag_DW_structure_type(), buf_ptr(&entry->name), |
| 272 | 262 | compile_unit_scope, di_file, line); |
| 273 | 263 | |
| 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 | 276 | LLVMZigDIType *di_element_types[] = { |
| 275 | 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, |
| 277 | | child_type->di_type), |
| 278 | "val", di_file, line, |
| 279 | val_debug_size_in_bits, |
| 280 | val_debug_align_in_bits, |
| 281 | val_offset_in_bits, |
| 282 | 0, child_type->di_type), |
| 278 | 283 | LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type), |
| 279 | | "maybe", di_file, line, 8, 8, child_type->size_in_bits, 0, |
| 280 | | child_type->di_type), |
| 284 | "maybe", di_file, line, |
| 285 | maybe_debug_size_in_bits, |
| 286 | maybe_debug_align_in_bits, |
| 287 | maybe_offset_in_bits, |
| 288 | 0, child_type->di_type), |
| 281 | 289 | }; |
| 282 | 290 | LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder, |
| 283 | 291 | compile_unit_scope, |
| 284 | 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 | 294 | nullptr, di_element_types, 2, 0, nullptr, ""); |
| 287 | 295 | |
| 288 | 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 | 317 | |
| 310 | 318 | entry->data.error.child_type = child_type; |
| 311 | 319 | |
| 312 | | if (child_type->size_in_bits == 0) { |
| 320 | if (!type_has_bits(child_type)) { |
| 313 | 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 | 322 | entry->di_type = g->err_tag_type->di_type; |
| 317 | 323 | |
| 318 | 324 | } else { |
| ... | ... | @@ -321,8 +327,6 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) { |
| 321 | 327 | child_type->type_ref, |
| 322 | 328 | }; |
| 323 | 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; |
| 326 | 330 | |
| 327 | 331 | LLVMZigDIScope *compile_unit_scope = LLVMZigCompileUnitToScope(g->compile_unit); |
| 328 | 332 | LLVMZigDIFile *di_file = nullptr; |
| ... | ... | @@ -331,19 +335,39 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) { |
| 331 | 335 | LLVMZigTag_DW_structure_type(), buf_ptr(&entry->name), |
| 332 | 336 | compile_unit_scope, di_file, line); |
| 333 | 337 | |
| 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 | 349 | LLVMZigDIType *di_element_types[] = { |
| 335 | 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, |
| 337 | | 0, 0, child_type->di_type), |
| 351 | "tag", di_file, line, |
| 352 | tag_debug_size_in_bits, |
| 353 | tag_debug_align_in_bits, |
| 354 | tag_offset_in_bits, |
| 355 | 0, child_type->di_type), |
| 338 | 356 | LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type), |
| 339 | | "value", di_file, line, child_type->size_in_bits, child_type->align_in_bits, |
| 340 | | g->err_tag_type->size_in_bits, 0, child_type->di_type), |
| 357 | "value", di_file, line, |
| 358 | value_debug_size_in_bits, |
| 359 | value_debug_align_in_bits, |
| 360 | value_offset_in_bits, |
| 361 | 0, child_type->di_type), |
| 341 | 362 | }; |
| 342 | 363 | |
| 343 | 364 | LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder, |
| 344 | 365 | compile_unit_scope, |
| 345 | 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 | 371 | nullptr, di_element_types, 2, 0, nullptr, ""); |
| 348 | 372 | |
| 349 | 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 | 387 | } else { |
| 364 | 388 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray); |
| 365 | 389 | entry->type_ref = LLVMArrayType(child_type->type_ref, array_size); |
| 390 | entry->zero_bits = (array_size == 0) || child_type->zero_bits; |
| 391 | |
| 366 | 392 | buf_resize(&entry->name, 0); |
| 367 | 393 | buf_appendf(&entry->name, "[%" PRIu64 "]%s", array_size, buf_ptr(&child_type->name)); |
| 368 | 394 | |
| 369 | | entry->size_in_bits = child_type->size_in_bits * array_size; |
| 370 | | entry->align_in_bits = child_type->align_in_bits; |
| 395 | uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, entry->type_ref); |
| 396 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref); |
| 371 | 397 | |
| 372 | | entry->di_type = LLVMZigCreateDebugArrayType(g->dbuilder, entry->size_in_bits, |
| 373 | | entry->align_in_bits, child_type->di_type, array_size); |
| 398 | entry->di_type = LLVMZigCreateDebugArrayType(g->dbuilder, debug_size_in_bits, |
| 399 | debug_align_in_bits, child_type->di_type, array_size); |
| 374 | 400 | entry->data.array.child_type = child_type; |
| 375 | 401 | entry->data.array.len = array_size; |
| 376 | 402 | |
| ... | ... | @@ -379,14 +405,12 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t |
| 379 | 405 | } |
| 380 | 406 | } |
| 381 | 407 | |
| 382 | | static void unknown_size_array_type_common_init(CodeGen *g, TypeTableEntry *child_type, |
| 408 | static void slice_type_common_init(CodeGen *g, TypeTableEntry *child_type, |
| 383 | 409 | bool is_const, TypeTableEntry *entry) |
| 384 | 410 | { |
| 385 | 411 | TypeTableEntry *pointer_type = get_pointer_to_type(g, child_type, is_const); |
| 386 | 412 | |
| 387 | 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 | 414 | entry->data.structure.is_packed = false; |
| 391 | 415 | entry->data.structure.is_unknown_size_array = true; |
| 392 | 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 | 426 | entry->data.structure.fields[1].gen_index = 1; |
| 403 | 427 | } |
| 404 | 428 | |
| 405 | | static TypeTableEntry *get_unknown_size_array_type(CodeGen *g, TypeTableEntry *child_type, bool is_const) { |
| 429 | static TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_const) { |
| 406 | 430 | assert(child_type->id != TypeTableEntryIdInvalid); |
| 407 | 431 | TypeTableEntry **parent_pointer = &child_type->unknown_size_array_parent[(is_const ? 1 : 0)]; |
| 408 | 432 | |
| 409 | 433 | if (*parent_pointer) { |
| 410 | 434 | return *parent_pointer; |
| 411 | 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 | 437 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct); |
| 414 | 438 | |
| 415 | 439 | buf_resize(&entry->name, 0); |
| 416 | 440 | buf_appendf(&entry->name, "[]const %s", buf_ptr(&child_type->name)); |
| 417 | 441 | |
| 418 | | unknown_size_array_type_common_init(g, child_type, is_const, entry); |
| 442 | slice_type_common_init(g, child_type, is_const, entry); |
| 419 | 443 | |
| 420 | 444 | entry->type_ref = var_peer->type_ref; |
| 421 | 445 | entry->di_type = var_peer->di_type; |
| ... | ... | @@ -439,15 +463,17 @@ static TypeTableEntry *get_unknown_size_array_type(CodeGen *g, TypeTableEntry *c |
| 439 | 463 | }; |
| 440 | 464 | LLVMStructSetBody(entry->type_ref, element_types, element_count, false); |
| 441 | 465 | |
| 442 | | unknown_size_array_type_common_init(g, child_type, is_const, entry); |
| 466 | slice_type_common_init(g, child_type, is_const, entry); |
| 443 | 467 | |
| 444 | 468 | LLVMZigDIType *di_element_types[] = { |
| 445 | 469 | pointer_type->di_type, |
| 446 | 470 | g->builtin_types.entry_isize->di_type, |
| 447 | 471 | }; |
| 448 | 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 | 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 | 477 | nullptr, di_element_types, element_count, 0, nullptr, ""); |
| 452 | 478 | |
| 453 | 479 | entry->data.structure.complete = true; |
| ... | ... | @@ -462,11 +488,9 @@ TypeTableEntry *get_typedecl_type(CodeGen *g, const char *name, TypeTableEntry * |
| 462 | 488 | |
| 463 | 489 | buf_init_from_str(&entry->name, name); |
| 464 | 490 | |
| 465 | | entry->type_ref = child_type->type_ref; |
| 466 | 491 | entry->type_ref = child_type->type_ref; |
| 467 | 492 | entry->di_type = child_type->di_type; |
| 468 | | entry->size_in_bits = child_type->size_in_bits; |
| 469 | | entry->align_in_bits = child_type->align_in_bits; |
| 493 | entry->zero_bits = child_type->zero_bits; |
| 470 | 494 | |
| 471 | 495 | entry->data.type_decl.child_type = child_type; |
| 472 | 496 | |
| ... | ... | @@ -497,9 +521,6 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId fn_type_id) { |
| 497 | 521 | fn_type->data.fn.calling_convention = LLVMFastCallConv; |
| 498 | 522 | } |
| 499 | 523 | |
| 500 | | fn_type->size_in_bits = g->pointer_size_bytes * 8; |
| 501 | | fn_type->align_in_bits = g->pointer_size_bytes * 8; |
| 502 | | |
| 503 | 524 | // populate the name of the type |
| 504 | 525 | buf_resize(&fn_type->name, 0); |
| 505 | 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 | 563 | // after the gen_param_index += 1 because 0 is the return type |
| 543 | 564 | param_di_types[gen_param_index] = gen_type->di_type; |
| 544 | 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 | 567 | gen_return_type = g->builtin_types.entry_void; |
| 547 | 568 | } else { |
| 548 | 569 | gen_return_type = fn_type_id.return_type; |
| ... | ... | @@ -559,7 +580,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId fn_type_id) { |
| 559 | 580 | gen_param_info->gen_index = -1; |
| 560 | 581 | |
| 561 | 582 | assert(type_is_complete(type_entry)); |
| 562 | | if (type_entry->size_in_bits > 0) { |
| 583 | if (type_has_bits(type_entry)) { |
| 563 | 584 | TypeTableEntry *gen_type; |
| 564 | 585 | if (handle_is_ptr(type_entry)) { |
| 565 | 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 | 918 | AstNode *field_node = decl_node->data.struct_decl.fields.at(i); |
| 898 | 919 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; |
| 899 | 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 | 922 | field_node->data.struct_field.type); |
| 923 | type_enum_field->type_entry = field_type; |
| 902 | 924 | type_enum_field->value = i; |
| 903 | 925 | |
| 926 | |
| 904 | 927 | di_enumerators[i] = LLVMZigCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i); |
| 905 | 928 | |
| 906 | | if (type_enum_field->type_entry->id == TypeTableEntryIdStruct) { |
| 907 | | resolve_struct_type(g, import, type_enum_field->type_entry); |
| 908 | | } else if (type_enum_field->type_entry->id == TypeTableEntryIdEnum) { |
| 909 | | resolve_enum_type(g, import, type_enum_field->type_entry); |
| 910 | | } else if (type_enum_field->type_entry->id == TypeTableEntryIdInvalid) { |
| 929 | if (field_type->id == TypeTableEntryIdStruct) { |
| 930 | resolve_struct_type(g, import, field_type); |
| 931 | } else if (field_type->id == TypeTableEntryIdEnum) { |
| 932 | resolve_enum_type(g, import, field_type); |
| 933 | } else if (field_type->id == TypeTableEntryIdInvalid) { |
| 911 | 934 | enum_type->data.enumeration.is_invalid = true; |
| 912 | 935 | continue; |
| 913 | | } else if (type_enum_field->type_entry->id == TypeTableEntryIdVoid) { |
| 936 | } else if (!type_has_bits(field_type)) { |
| 914 | 937 | continue; |
| 915 | 938 | } |
| 916 | 939 | |
| 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 | 943 | union_inner_di_types[gen_field_index] = LLVMZigCreateDebugMemberType(g->dbuilder, |
| 918 | 944 | LLVMZigTypeToScope(enum_type->di_type), buf_ptr(type_enum_field->name), |
| 919 | 945 | import->di_file, field_node->line + 1, |
| 920 | | type_enum_field->type_entry->size_in_bits, |
| 921 | | type_enum_field->type_entry->align_in_bits, |
| 922 | | 0, 0, type_enum_field->type_entry->di_type); |
| 946 | debug_size_in_bits, |
| 947 | debug_align_in_bits, |
| 948 | 0, |
| 949 | 0, field_type->di_type); |
| 923 | 950 | |
| 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); |
| 925 | 952 | |
| 926 | 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; |
| 930 | | biggest_union_member_size_in_bits = biggest_union_member->size_in_bits; |
| 956 | biggest_union_member = field_type; |
| 957 | biggest_union_member_size_in_bits = debug_size_in_bits; |
| 931 | 958 | } |
| 932 | 959 | |
| 933 | 960 | gen_field_index += 1; |
| ... | ... | @@ -941,8 +968,6 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt |
| 941 | 968 | enum_type->data.enumeration.gen_field_count = gen_field_index; |
| 942 | 969 | |
| 943 | 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 | 971 | enum_type->data.enumeration.tag_type = tag_type_entry; |
| 947 | 972 | |
| 948 | 973 | if (biggest_union_member) { |
| ... | ... | @@ -958,30 +983,37 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt |
| 958 | 983 | LLVMStructSetBody(enum_type->type_ref, root_struct_element_types, 2, false); |
| 959 | 984 | |
| 960 | 985 | // 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 | 988 | LLVMZigDIType *tag_di_type = LLVMZigCreateDebugEnumerationType(g->dbuilder, |
| 962 | 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 | 991 | tag_type_entry->di_type, ""); |
| 965 | 992 | |
| 966 | 993 | // create debug type for union |
| 967 | 994 | LLVMZigDIType *union_di_type = LLVMZigCreateDebugUnionType(g->dbuilder, |
| 968 | 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 | 997 | gen_field_index, 0, ""); |
| 971 | 998 | |
| 972 | 999 | // 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 | 1001 | LLVMZigDIType *tag_member_di_type = LLVMZigCreateDebugMemberType(g->dbuilder, |
| 974 | 1002 | LLVMZigTypeToScope(enum_type->di_type), "tag_field", |
| 975 | 1003 | import->di_file, decl_node->line + 1, |
| 976 | | tag_type_entry->size_in_bits, |
| 977 | | tag_type_entry->align_in_bits, |
| 978 | | 0, 0, tag_di_type); |
| 1004 | tag_debug_size_in_bits, |
| 1005 | tag_debug_align_in_bits, |
| 1006 | tag_offset_in_bits, |
| 1007 | 0, tag_di_type); |
| 1008 | |
| 1009 | uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, enum_type->type_ref, 1); |
| 979 | 1010 | LLVMZigDIType *union_member_di_type = LLVMZigCreateDebugMemberType(g->dbuilder, |
| 980 | 1011 | LLVMZigTypeToScope(enum_type->di_type), "union_field", |
| 981 | 1012 | import->di_file, decl_node->line + 1, |
| 982 | | biggest_union_member->size_in_bits, |
| 1013 | biggest_union_member_size_in_bits, |
| 983 | 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); |
| 985 | 1017 | |
| 986 | 1018 | // create debug type for root struct |
| 987 | 1019 | LLVMZigDIType *di_root_members[] = { |
| ... | ... | @@ -990,11 +1022,15 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt |
| 990 | 1022 | }; |
| 991 | 1023 | |
| 992 | 1024 | |
| 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 | 1027 | LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder, |
| 994 | 1028 | LLVMZigFileToScope(import->di_file), |
| 995 | 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, |
| 997 | | nullptr, di_root_members, 2, 0, nullptr, ""); |
| 1030 | import->di_file, decl_node->line + 1, |
| 1031 | debug_size_in_bits, |
| 1032 | debug_align_in_bits, |
| 1033 | 0, nullptr, di_root_members, 2, 0, nullptr, ""); |
| 998 | 1034 | |
| 999 | 1035 | LLVMZigReplaceTemporary(g->dbuilder, enum_type->di_type, replacement_di_type); |
| 1000 | 1036 | enum_type->di_type = replacement_di_type; |
| ... | ... | @@ -1003,10 +1039,14 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt |
| 1003 | 1039 | enum_type->type_ref = tag_type_entry->type_ref; |
| 1004 | 1040 | |
| 1005 | 1041 | // 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 | 1044 | LLVMZigDIType *tag_di_type = LLVMZigCreateDebugEnumerationType(g->dbuilder, |
| 1007 | 1045 | LLVMZigFileToScope(import->di_file), buf_ptr(&decl_node->data.struct_decl.name), |
| 1008 | 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 | 1050 | tag_type_entry->di_type, ""); |
| 1011 | 1051 | |
| 1012 | 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 | 1065 | AstNode *decl_node = struct_type->data.structure.decl_node; |
| 1026 | 1066 | |
| 1027 | 1067 | if (struct_type->data.structure.embedded_in_current) { |
| 1068 | struct_type->data.structure.is_invalid = true; |
| 1028 | 1069 | if (!struct_type->data.structure.reported_infinite_err) { |
| 1029 | 1070 | struct_type->data.structure.reported_infinite_err = true; |
| 1030 | 1071 | add_node_error(g, decl_node, |
| ... | ... | @@ -1049,11 +1090,6 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE |
| 1049 | 1090 | // we possibly allocate too much here since gen_field_count can be lower than field_count. |
| 1050 | 1091 | // the only problem is potential wasted space though. |
| 1051 | 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; |
| 1057 | 1093 | |
| 1058 | 1094 | // this field should be set to true only during the recursive calls to resolve_struct_type |
| 1059 | 1095 | struct_type->data.structure.embedded_in_current = true; |
| ... | ... | @@ -1063,41 +1099,28 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE |
| 1063 | 1099 | AstNode *field_node = decl_node->data.struct_decl.fields.at(i); |
| 1064 | 1100 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; |
| 1065 | 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 | 1103 | field_node->data.struct_field.type); |
| 1104 | type_struct_field->type_entry = field_type; |
| 1068 | 1105 | type_struct_field->src_index = i; |
| 1069 | 1106 | type_struct_field->gen_index = -1; |
| 1070 | 1107 | |
| 1071 | | if (type_struct_field->type_entry->id == TypeTableEntryIdStruct) { |
| 1072 | | resolve_struct_type(g, import, type_struct_field->type_entry); |
| 1073 | | } else if (type_struct_field->type_entry->id == TypeTableEntryIdEnum) { |
| 1074 | | resolve_enum_type(g, import, type_struct_field->type_entry); |
| 1075 | | } else if (type_struct_field->type_entry->id == TypeTableEntryIdInvalid) { |
| 1108 | if (field_type->id == TypeTableEntryIdStruct) { |
| 1109 | resolve_struct_type(g, import, field_type); |
| 1110 | } else if (field_type->id == TypeTableEntryIdEnum) { |
| 1111 | resolve_enum_type(g, import, field_type); |
| 1112 | } else if (field_type->id == TypeTableEntryIdInvalid) { |
| 1076 | 1113 | struct_type->data.structure.is_invalid = true; |
| 1077 | 1114 | continue; |
| 1078 | | } else if (type_struct_field->type_entry->id == TypeTableEntryIdVoid) { |
| 1115 | } else if (!type_has_bits(field_type)) { |
| 1079 | 1116 | continue; |
| 1080 | 1117 | } |
| 1081 | 1118 | |
| 1082 | 1119 | type_struct_field->gen_index = gen_field_index; |
| 1083 | 1120 | |
| 1084 | | di_element_types[gen_field_index] = LLVMZigCreateDebugMemberType(g->dbuilder, |
| 1085 | | LLVMZigTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name), |
| 1086 | | import->di_file, field_node->line + 1, |
| 1087 | | type_struct_field->type_entry->size_in_bits, |
| 1088 | | type_struct_field->type_entry->align_in_bits, |
| 1089 | | offset_in_bits, 0, type_struct_field->type_entry->di_type); |
| 1090 | | |
| 1091 | | element_types[gen_field_index] = type_struct_field->type_entry->type_ref; |
| 1092 | | assert(di_element_types[gen_field_index]); |
| 1121 | element_types[gen_field_index] = field_type->type_ref; |
| 1093 | 1122 | assert(element_types[gen_field_index]); |
| 1094 | 1123 | |
| 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 | 1124 | gen_field_index += 1; |
| 1102 | 1125 | } |
| 1103 | 1126 | struct_type->data.structure.embedded_in_current = false; |
| ... | ... | @@ -1105,22 +1128,55 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE |
| 1105 | 1128 | struct_type->data.structure.gen_field_count = gen_field_index; |
| 1106 | 1129 | struct_type->data.structure.complete = true; |
| 1107 | 1130 | |
| 1108 | | if (!struct_type->data.structure.is_invalid) { |
| 1131 | if (struct_type->data.structure.is_invalid) { |
| 1132 | return; |
| 1133 | } |
| 1109 | 1134 | |
| 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); |
| 1111 | 1137 | |
| 1112 | | struct_type->align_in_bits = first_field_align_in_bits; |
| 1113 | | struct_type->size_in_bits = total_size_in_bits; |
| 1138 | LLVMZigDIType **di_element_types = allocate<LLVMZigDIType*>(gen_field_count); |
| 1114 | 1139 | |
| 1115 | | LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder, |
| 1116 | | LLVMZigFileToScope(import->di_file), |
| 1117 | | buf_ptr(&decl_node->data.struct_decl.name), |
| 1118 | | import->di_file, decl_node->line + 1, struct_type->size_in_bits, struct_type->align_in_bits, 0, |
| 1119 | | nullptr, di_element_types, gen_field_index, 0, nullptr, ""); |
| 1140 | for (int i = 0; i < field_count; i += 1) { |
| 1141 | AstNode *field_node = decl_node->data.struct_decl.fields.at(i); |
| 1142 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; |
| 1143 | gen_field_index = type_struct_field->gen_index; |
| 1144 | if (gen_field_index == -1) { |
| 1145 | continue; |
| 1146 | } |
| 1147 | |
| 1148 | TypeTableEntry *field_type = type_struct_field->type_entry; |
| 1149 | |
| 1150 | uint64_t debug_size_in_bits = LLVMSizeOfTypeInBits(g->target_data_ref, field_type->type_ref); |
| 1151 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, field_type->type_ref); |
| 1152 | uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref, |
| 1153 | gen_field_index); |
| 1154 | di_element_types[gen_field_index] = LLVMZigCreateDebugMemberType(g->dbuilder, |
| 1155 | LLVMZigTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name), |
| 1156 | import->di_file, field_node->line + 1, |
| 1157 | debug_size_in_bits, |
| 1158 | debug_align_in_bits, |
| 1159 | debug_offset_in_bits, |
| 1160 | 0, field_type->di_type); |
| 1120 | 1161 | |
| 1121 | | LLVMZigReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type); |
| 1122 | | struct_type->di_type = replacement_di_type; |
| 1162 | assert(di_element_types[gen_field_index]); |
| 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 | } |
| 1125 | 1181 | |
| 1126 | 1182 | static void preview_fn_proto(CodeGen *g, ImportTableEntry *import, |
| ... | ... | @@ -1498,7 +1554,7 @@ static void add_global_const_expr(CodeGen *g, Expr *expr) { |
| 1498 | 1554 | if (expr->const_val.ok && |
| 1499 | 1555 | type_has_codegen_value(expr->type_entry) && |
| 1500 | 1556 | !expr->has_global_const && |
| 1501 | | expr->type_entry->size_in_bits > 0) |
| 1557 | type_has_bits(expr->type_entry)) |
| 1502 | 1558 | { |
| 1503 | 1559 | g->global_const_list.append(expr); |
| 1504 | 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 | 1573 | } else if (other_type->id == TypeTableEntryIdInt && |
| 1518 | 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 | 1577 | other_type->data.integral.is_signed)) |
| 1522 | 1578 | { |
| 1523 | 1579 | return true; |
| ... | ... | @@ -1653,14 +1709,14 @@ static TypeTableEntry *determine_peer_type_compatibility(CodeGen *g, AstNode *pa |
| 1653 | 1709 | cur_type->id == TypeTableEntryIdInt && |
| 1654 | 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 | 1713 | prev_type = cur_type; |
| 1658 | 1714 | prev_node = cur_node; |
| 1659 | 1715 | } |
| 1660 | 1716 | } else if (prev_type->id == TypeTableEntryIdFloat && |
| 1661 | 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 | 1720 | prev_type = cur_type; |
| 1665 | 1721 | prev_node = cur_node; |
| 1666 | 1722 | } |
| ... | ... | @@ -1737,7 +1793,7 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_ |
| 1737 | 1793 | if (expected_type->id == TypeTableEntryIdInt && |
| 1738 | 1794 | actual_type->id == TypeTableEntryIdInt && |
| 1739 | 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 | 1798 | return true; |
| 1743 | 1799 | } |
| ... | ... | @@ -1745,7 +1801,7 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_ |
| 1745 | 1801 | // implicit float widening conversion |
| 1746 | 1802 | if (expected_type->id == TypeTableEntryIdFloat && |
| 1747 | 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 | 1806 | return true; |
| 1751 | 1807 | } |
| ... | ... | @@ -2221,15 +2277,15 @@ static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import, |
| 2221 | 2277 | if (array_type->id == TypeTableEntryIdInvalid) { |
| 2222 | 2278 | return_type = g->builtin_types.entry_invalid; |
| 2223 | 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 | 2281 | node->data.slice_expr.is_const); |
| 2226 | 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 | 2284 | node->data.slice_expr.is_const); |
| 2229 | 2285 | } else if (array_type->id == TypeTableEntryIdStruct && |
| 2230 | 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 | 2289 | array_type->data.structure.fields[0].type_entry->data.pointer.child_type, |
| 2234 | 2290 | node->data.slice_expr.is_const); |
| 2235 | 2291 | } else { |
| ... | ... | @@ -2666,7 +2722,7 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im |
| 2666 | 2722 | bool are_equal = false; |
| 2667 | 2723 | if (enum1->tag == enum2->tag) { |
| 2668 | 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 | 2726 | zig_panic("TODO const expr analyze enum special value for equality"); |
| 2671 | 2727 | } else { |
| 2672 | 2728 | are_equal = true; |
| ... | ... | @@ -2839,7 +2895,7 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import, |
| 2839 | 2895 | AstNode **op1 = node->data.bin_op_expr.op1->parent_field; |
| 2840 | 2896 | AstNode **op2 = node->data.bin_op_expr.op2->parent_field; |
| 2841 | 2897 | |
| 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); |
| 2843 | 2899 | |
| 2844 | 2900 | TypeTableEntry *op1_type = analyze_expression(g, import, context, str_type, *op1); |
| 2845 | 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 | 3218 | } |
| 3163 | 3219 | } else { |
| 3164 | 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 | 3223 | } else { |
| 3168 | 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 | } |
| 3172 | 3228 | |
| ... | ... | @@ -3357,13 +3413,13 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor |
| 3357 | 3413 | if (is_max) { |
| 3358 | 3414 | if (type_entry->data.integral.is_signed) { |
| 3359 | 3415 | int64_t val; |
| 3360 | | if (type_entry->size_in_bits == 64) { |
| 3416 | if (type_entry->data.integral.bit_count == 64) { |
| 3361 | 3417 | val = INT64_MAX; |
| 3362 | | } else if (type_entry->size_in_bits == 32) { |
| 3418 | } else if (type_entry->data.integral.bit_count == 32) { |
| 3363 | 3419 | val = INT32_MAX; |
| 3364 | | } else if (type_entry->size_in_bits == 16) { |
| 3420 | } else if (type_entry->data.integral.bit_count == 16) { |
| 3365 | 3421 | val = INT16_MAX; |
| 3366 | | } else if (type_entry->size_in_bits == 8) { |
| 3422 | } else if (type_entry->data.integral.bit_count == 8) { |
| 3367 | 3423 | val = INT8_MAX; |
| 3368 | 3424 | } else { |
| 3369 | 3425 | zig_unreachable(); |
| ... | ... | @@ -3371,13 +3427,13 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor |
| 3371 | 3427 | bignum_init_signed(&const_val->data.x_bignum, val); |
| 3372 | 3428 | } else { |
| 3373 | 3429 | uint64_t val; |
| 3374 | | if (type_entry->size_in_bits == 64) { |
| 3430 | if (type_entry->data.integral.bit_count == 64) { |
| 3375 | 3431 | val = UINT64_MAX; |
| 3376 | | } else if (type_entry->size_in_bits == 32) { |
| 3432 | } else if (type_entry->data.integral.bit_count == 32) { |
| 3377 | 3433 | val = UINT32_MAX; |
| 3378 | | } else if (type_entry->size_in_bits == 16) { |
| 3434 | } else if (type_entry->data.integral.bit_count == 16) { |
| 3379 | 3435 | val = UINT16_MAX; |
| 3380 | | } else if (type_entry->size_in_bits == 8) { |
| 3436 | } else if (type_entry->data.integral.bit_count == 8) { |
| 3381 | 3437 | val = UINT8_MAX; |
| 3382 | 3438 | } else { |
| 3383 | 3439 | zig_unreachable(); |
| ... | ... | @@ -3387,13 +3443,13 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor |
| 3387 | 3443 | } else { |
| 3388 | 3444 | if (type_entry->data.integral.is_signed) { |
| 3389 | 3445 | int64_t val; |
| 3390 | | if (type_entry->size_in_bits == 64) { |
| 3446 | if (type_entry->data.integral.bit_count == 64) { |
| 3391 | 3447 | val = INT64_MIN; |
| 3392 | | } else if (type_entry->size_in_bits == 32) { |
| 3448 | } else if (type_entry->data.integral.bit_count == 32) { |
| 3393 | 3449 | val = INT32_MIN; |
| 3394 | | } else if (type_entry->size_in_bits == 16) { |
| 3450 | } else if (type_entry->data.integral.bit_count == 16) { |
| 3395 | 3451 | val = INT16_MIN; |
| 3396 | | } else if (type_entry->size_in_bits == 8) { |
| 3452 | } else if (type_entry->data.integral.bit_count == 8) { |
| 3397 | 3453 | val = INT8_MIN; |
| 3398 | 3454 | } else { |
| 3399 | 3455 | zig_unreachable(); |
| ... | ... | @@ -3657,14 +3713,16 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B |
| 3657 | 3713 | |
| 3658 | 3714 | // explicit cast from %void to integer type which can fit it |
| 3659 | 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 | 3717 | bool actual_type_is_pure_err = actual_type->id == TypeTableEntryIdPureError; |
| 3662 | 3718 | if ((actual_type_is_void_err || actual_type_is_pure_err) && |
| 3663 | 3719 | wanted_type->id == TypeTableEntryIdInt) |
| 3664 | 3720 | { |
| 3665 | 3721 | BigNum bn; |
| 3666 | 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 | 3726 | node->data.fn_call_expr.cast_op = CastOpErrToInt; |
| 3669 | 3727 | eval_const_expr_implicit_cast(g, node, expr_node); |
| 3670 | 3728 | return wanted_type; |
| ... | ... | @@ -3767,13 +3825,13 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry |
| 3767 | 3825 | if (dest_type->id == TypeTableEntryIdPointer && |
| 3768 | 3826 | src_type->id == TypeTableEntryIdPointer) |
| 3769 | 3827 | { |
| 3770 | | uint64_t dest_align_bits = dest_type->data.pointer.child_type->align_in_bits; |
| 3771 | | uint64_t src_align_bits = src_type->data.pointer.child_type->align_in_bits; |
| 3772 | | if (dest_align_bits != src_align_bits) { |
| 3828 | uint64_t dest_align = get_memcpy_align(g, dest_type->data.pointer.child_type); |
| 3829 | uint64_t src_align = get_memcpy_align(g, src_type->data.pointer.child_type); |
| 3830 | if (dest_align != src_align) { |
| 3773 | 3831 | add_node_error(g, dest_node, buf_sprintf( |
| 3774 | 3832 | "misaligned memcpy, '%s' has alignment '%" PRIu64 ", '%s' has alignment %" PRIu64, |
| 3775 | | buf_ptr(&dest_type->name), dest_align_bits / 8, |
| 3776 | | buf_ptr(&src_type->name), src_align_bits / 8)); |
| 3833 | buf_ptr(&dest_type->name), dest_align, |
| 3834 | buf_ptr(&src_type->name), src_align)); |
| 3777 | 3835 | } |
| 3778 | 3836 | } |
| 3779 | 3837 | |
| ... | ... | @@ -3808,10 +3866,30 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry |
| 3808 | 3866 | buf_sprintf("no size available for type '%s'", buf_ptr(&type_entry->name))); |
| 3809 | 3867 | return g->builtin_types.entry_invalid; |
| 3810 | 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 | 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 | 3893 | case BuiltinFnIdMaxValue: |
| 3816 | 3894 | return analyze_min_max_value(g, import, context, node, |
| 3817 | 3895 | "no max value available for type '%s'", true); |
| ... | ... | @@ -3874,7 +3952,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry |
| 3874 | 3952 | } |
| 3875 | 3953 | |
| 3876 | 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 | 3956 | TypeTableEntry *resolved_type = analyze_expression(g, import, context, str_type, *str_node); |
| 3879 | 3957 | |
| 3880 | 3958 | if (resolved_type->id == TypeTableEntryIdInvalid) { |
| ... | ... | @@ -3911,7 +3989,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry |
| 3911 | 3989 | { |
| 3912 | 3990 | AstNode **str_node = node->data.fn_call_expr.params.at(0)->parent_field; |
| 3913 | 3991 | |
| 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 | 3993 | TypeTableEntry *resolved_type = analyze_expression(g, import, context, str_type, *str_node); |
| 3916 | 3994 | |
| 3917 | 3995 | if (resolved_type->id == TypeTableEntryIdInvalid) { |
| ... | ... | @@ -5317,8 +5395,6 @@ void semantic_analyze(CodeGen *g) { |
| 5317 | 5395 | g->err_tag_type = get_smallest_unsigned_int_type(g, g->error_value_count); |
| 5318 | 5396 | |
| 5319 | 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 | 5398 | g->builtin_types.entry_pure_error->di_type = g->err_tag_type->di_type; |
| 5323 | 5399 | } |
| 5324 | 5400 | |
| ... | ... | @@ -5571,7 +5647,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) { |
| 5571 | 5647 | case TypeTableEntryIdStruct: |
| 5572 | 5648 | return true; |
| 5573 | 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 | 5651 | case TypeTableEntryIdEnum: |
| 5576 | 5652 | return type_entry->data.enumeration.gen_field_count != 0; |
| 5577 | 5653 | case TypeTableEntryIdMaybe: |
| ... | ... | @@ -5640,3 +5716,59 @@ bool fn_type_id_eql(FnTypeId a, FnTypeId b) { |
| 5640 | 5716 | } |
| 5641 | 5717 | return true; |
| 5642 | 5718 | } |
| 5719 | |
| 5720 | bool type_has_bits(TypeTableEntry *type_entry) { |
| 5721 | assert(type_entry); |
| 5722 | assert(type_entry->id != TypeTableEntryIdInvalid); |
| 5723 | return !type_entry->zero_bits; |
| 5724 | } |
| 5725 | |
| 5726 | static 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 | |
| 5737 | static 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 | |
| 5770 | uint64_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 | |