| ... | ... | @@ -27,6 +27,7 @@ static Error ATTRIBUTE_MUST_USE resolve_enum_zero_bits(CodeGen *g, ZigType *enum |
| 27 | 27 | static Error ATTRIBUTE_MUST_USE resolve_union_zero_bits(CodeGen *g, ZigType *union_type); |
| 28 | 28 | static Error ATTRIBUTE_MUST_USE resolve_union_alignment(CodeGen *g, ZigType *union_type); |
| 29 | 29 | static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry); |
| 30 | static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status); |
| 30 | 31 | |
| 31 | 32 | static bool is_top_level_struct(ZigType *import) { |
| 32 | 33 | return import->id == ZigTypeIdStruct && import->data.structure.root_struct != nullptr; |
| ... | ... | @@ -278,6 +279,9 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) { |
| 278 | 279 | return type_entry->data.enumeration.zero_bits_known; |
| 279 | 280 | case ResolveStatusSizeKnown: |
| 280 | 281 | return type_entry->data.enumeration.complete; |
| 282 | case ResolveStatusLLVMFwdDecl: |
| 283 | case ResolveStatusLLVMFull: |
| 284 | return type_entry->llvm_di_type != nullptr; |
| 281 | 285 | } |
| 282 | 286 | zig_unreachable(); |
| 283 | 287 | case ZigTypeIdOpaque: |
| ... | ... | @@ -1120,6 +1124,7 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType |
| 1120 | 1124 | ZigType *elem_type = type_entry->data.array.child_type; |
| 1121 | 1125 | if ((err = emit_error_unless_type_allowed_in_packed_struct(g, elem_type, source_node))) |
| 1122 | 1126 | return err; |
| 1127 | // TODO revisit this when doing https://github.com/ziglang/zig/issues/1512 |
| 1123 | 1128 | if (type_size(g, type_entry) * 8 == type_size_bits(g, type_entry)) |
| 1124 | 1129 | return ErrorNone; |
| 1125 | 1130 | add_node_error(g, source_node, |
| ... | ... | @@ -1559,8 +1564,21 @@ ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_na |
| 1559 | 1564 | return struct_type; |
| 1560 | 1565 | } |
| 1561 | 1566 | |
| 1562 | | static size_t get_store_size_in_bits(size_t size_in_bits) { |
| 1563 | | return ((size_in_bits + 7) / 8) * 8; |
| 1567 | static size_t get_store_size_bytes(size_t size_in_bits) { |
| 1568 | return (size_in_bits + 7) / 8; |
| 1569 | } |
| 1570 | |
| 1571 | static size_t get_abi_align_bytes(size_t size_in_bits, size_t pointer_size_bytes) { |
| 1572 | size_t store_size_bytes = get_store_size_bytes(size_in_bits); |
| 1573 | if (store_size_bytes >= pointer_size_bytes) |
| 1574 | return pointer_size_bytes; |
| 1575 | return round_to_next_power_of_2(store_size_bytes); |
| 1576 | } |
| 1577 | |
| 1578 | static size_t get_abi_size_bytes(size_t size_in_bits, size_t pointer_size_bytes) { |
| 1579 | size_t store_size_bytes = get_store_size_bytes(size_in_bits); |
| 1580 | size_t abi_align = get_abi_align_bytes(size_in_bits, pointer_size_bytes); |
| 1581 | return align_forward(store_size_bytes, abi_align); |
| 1564 | 1582 | } |
| 1565 | 1583 | |
| 1566 | 1584 | static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| ... | ... | @@ -1637,17 +1655,18 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| 1637 | 1655 | field->bit_offset_in_host = packed_bits_offset - first_packed_bits_offset_misalign; |
| 1638 | 1656 | |
| 1639 | 1657 | size_t full_bit_count = next_packed_bits_offset - first_packed_bits_offset_misalign; |
| 1640 | | if (get_store_size_in_bits(full_bit_count) == full_bit_count) { |
| 1641 | | // next field recovers store alignment |
| 1642 | | host_int_bytes[gen_field_index] = full_bit_count / 8; |
| 1658 | size_t full_abi_size = get_abi_size_bytes(full_bit_count, g->pointer_size_bytes); |
| 1659 | if (full_abi_size * 8 == full_bit_count) { |
| 1660 | // next field recovers ABI alignment |
| 1661 | host_int_bytes[gen_field_index] = full_abi_size; |
| 1643 | 1662 | gen_field_index += 1; |
| 1644 | 1663 | // TODO: https://github.com/ziglang/zig/issues/1512 |
| 1645 | | next_offset = next_field_offset(next_offset, abi_align, full_bit_count / 8, 1); |
| 1664 | next_offset = next_field_offset(next_offset, abi_align, full_abi_size, 1); |
| 1646 | 1665 | size_in_bits = next_offset * 8; |
| 1647 | 1666 | |
| 1648 | 1667 | first_packed_bits_offset_misalign = SIZE_MAX; |
| 1649 | 1668 | } |
| 1650 | | } else if (get_store_size_in_bits(field_type->size_in_bits) != field_size_in_bits) { |
| 1669 | } else if (get_abi_size_bytes(field_type->size_in_bits, g->pointer_size_bytes) * 8 != field_size_in_bits) { |
| 1651 | 1670 | first_packed_bits_offset_misalign = packed_bits_offset; |
| 1652 | 1671 | field->bit_offset_in_host = 0; |
| 1653 | 1672 | } else { |
| ... | ... | @@ -1676,9 +1695,9 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| 1676 | 1695 | } |
| 1677 | 1696 | if (first_packed_bits_offset_misalign != SIZE_MAX) { |
| 1678 | 1697 | size_t full_bit_count = packed_bits_offset - first_packed_bits_offset_misalign; |
| 1679 | | size_t store_bit_count = get_store_size_in_bits(full_bit_count); |
| 1680 | | next_offset = next_field_offset(next_offset, abi_align, store_bit_count / 8, 1); |
| 1681 | | host_int_bytes[gen_field_index] = store_bit_count / 8; |
| 1698 | size_t full_abi_size = get_abi_size_bytes(full_bit_count, g->pointer_size_bytes); |
| 1699 | next_offset = next_field_offset(next_offset, abi_align, full_abi_size, abi_align); |
| 1700 | host_int_bytes[gen_field_index] = full_abi_size; |
| 1682 | 1701 | gen_field_index += 1; |
| 1683 | 1702 | } |
| 1684 | 1703 | |
| ... | ... | @@ -4986,6 +5005,10 @@ Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) { |
| 4986 | 5005 | return resolve_union_type(g, ty); |
| 4987 | 5006 | } |
| 4988 | 5007 | return ErrorNone; |
| 5008 | case ResolveStatusLLVMFwdDecl: |
| 5009 | case ResolveStatusLLVMFull: |
| 5010 | resolve_llvm_types(g, ty, status); |
| 5011 | return ErrorNone; |
| 4989 | 5012 | } |
| 4990 | 5013 | zig_unreachable(); |
| 4991 | 5014 | } |
| ... | ... | @@ -6223,57 +6246,68 @@ Buf *type_h_name(ZigType *t) { |
| 6223 | 6246 | return type_bare_name(t); |
| 6224 | 6247 | } |
| 6225 | 6248 | |
| 6226 | | static void resolve_llvm_types_slice(CodeGen *g, ZigType *type) { |
| 6249 | static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) { |
| 6250 | if (type->data.structure.resolve_status >= wanted_resolve_status) return; |
| 6251 | |
| 6227 | 6252 | ZigType *ptr_type = type->data.structure.fields[slice_ptr_index].type_entry; |
| 6228 | 6253 | ZigType *child_type = ptr_type->data.pointer.child_type; |
| 6254 | ZigType *usize_type = g->builtin_types.entry_usize; |
| 6255 | LLVMTypeRef usize_llvm_type = get_llvm_type(g, usize_type); |
| 6256 | ZigLLVMDIType *usize_llvm_di_type = get_llvm_di_type(g, usize_type); |
| 6257 | ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit); |
| 6258 | ZigLLVMDIFile *di_file = nullptr; |
| 6259 | unsigned line = 0; |
| 6229 | 6260 | |
| 6230 | | if (ptr_type->data.pointer.is_const || ptr_type->data.pointer.is_volatile || |
| 6231 | | ptr_type->data.pointer.explicit_alignment != 0 || ptr_type->data.pointer.allow_zero) |
| 6232 | | { |
| 6233 | | ZigType *peer_ptr_type = get_pointer_to_type_extra(g, child_type, false, false, |
| 6234 | | PtrLenUnknown, 0, 0, 0, false); |
| 6235 | | ZigType *peer_slice_type = get_slice_type(g, peer_ptr_type); |
| 6236 | | |
| 6237 | | type->llvm_type = get_llvm_type(g, peer_slice_type); |
| 6238 | | type->llvm_di_type = get_llvm_di_type(g, peer_slice_type); |
| 6239 | | } |
| 6240 | | |
| 6241 | | // If the child type is []const T then we need to make sure the type ref |
| 6242 | | // and debug info is the same as if the child type were []T. |
| 6243 | | if (is_slice(child_type)) { |
| 6244 | | ZigType *child_ptr_type = child_type->data.structure.fields[slice_ptr_index].type_entry; |
| 6245 | | assert(child_ptr_type->id == ZigTypeIdPointer); |
| 6246 | | if (child_ptr_type->data.pointer.is_const || child_ptr_type->data.pointer.is_volatile || |
| 6247 | | child_ptr_type->data.pointer.explicit_alignment != 0 || child_ptr_type->data.pointer.allow_zero) |
| 6261 | if (type->data.structure.resolve_status < ResolveStatusLLVMFwdDecl) { |
| 6262 | bool done = false; |
| 6263 | if (ptr_type->data.pointer.is_const || ptr_type->data.pointer.is_volatile || |
| 6264 | ptr_type->data.pointer.explicit_alignment != 0 || ptr_type->data.pointer.allow_zero) |
| 6248 | 6265 | { |
| 6249 | | ZigType *grand_child_type = child_ptr_type->data.pointer.child_type; |
| 6250 | | ZigType *bland_child_ptr_type = get_pointer_to_type_extra(g, grand_child_type, false, false, |
| 6251 | | PtrLenUnknown, 0, 0, 0, false); |
| 6252 | | ZigType *bland_child_slice = get_slice_type(g, bland_child_ptr_type); |
| 6253 | | ZigType *peer_ptr_type = get_pointer_to_type_extra(g, bland_child_slice, false, false, |
| 6266 | ZigType *peer_ptr_type = get_pointer_to_type_extra(g, child_type, false, false, |
| 6254 | 6267 | PtrLenUnknown, 0, 0, 0, false); |
| 6255 | 6268 | ZigType *peer_slice_type = get_slice_type(g, peer_ptr_type); |
| 6256 | 6269 | |
| 6257 | 6270 | type->llvm_type = get_llvm_type(g, peer_slice_type); |
| 6258 | 6271 | type->llvm_di_type = get_llvm_di_type(g, peer_slice_type); |
| 6272 | done = true; |
| 6259 | 6273 | } |
| 6260 | | } |
| 6261 | 6274 | |
| 6262 | | if (type->llvm_type != nullptr) |
| 6263 | | return; |
| 6275 | // If the child type is []const T then we need to make sure the type ref |
| 6276 | // and debug info is the same as if the child type were []T. |
| 6277 | if (is_slice(child_type)) { |
| 6278 | ZigType *child_ptr_type = child_type->data.structure.fields[slice_ptr_index].type_entry; |
| 6279 | assert(child_ptr_type->id == ZigTypeIdPointer); |
| 6280 | if (child_ptr_type->data.pointer.is_const || child_ptr_type->data.pointer.is_volatile || |
| 6281 | child_ptr_type->data.pointer.explicit_alignment != 0 || child_ptr_type->data.pointer.allow_zero) |
| 6282 | { |
| 6283 | ZigType *grand_child_type = child_ptr_type->data.pointer.child_type; |
| 6284 | ZigType *bland_child_ptr_type = get_pointer_to_type_extra(g, grand_child_type, false, false, |
| 6285 | PtrLenUnknown, 0, 0, 0, false); |
| 6286 | ZigType *bland_child_slice = get_slice_type(g, bland_child_ptr_type); |
| 6287 | ZigType *peer_ptr_type = get_pointer_to_type_extra(g, bland_child_slice, false, false, |
| 6288 | PtrLenUnknown, 0, 0, 0, false); |
| 6289 | ZigType *peer_slice_type = get_slice_type(g, peer_ptr_type); |
| 6290 | |
| 6291 | type->llvm_type = get_llvm_type(g, peer_slice_type); |
| 6292 | type->llvm_di_type = get_llvm_di_type(g, peer_slice_type); |
| 6293 | done = true; |
| 6294 | } |
| 6295 | } |
| 6264 | 6296 | |
| 6265 | | ZigType *usize_type = g->builtin_types.entry_usize; |
| 6266 | | LLVMTypeRef usize_llvm_type = get_llvm_type(g, usize_type); |
| 6267 | | ZigLLVMDIType *usize_llvm_di_type = get_llvm_di_type(g, usize_type); |
| 6297 | if (done) { |
| 6298 | type->data.structure.resolve_status = ResolveStatusLLVMFull; |
| 6299 | return; |
| 6300 | } |
| 6268 | 6301 | |
| 6269 | | type->llvm_type = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&type->name)); |
| 6302 | type->llvm_type = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&type->name)); |
| 6270 | 6303 | |
| 6271 | | ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit); |
| 6272 | | ZigLLVMDIFile *di_file = nullptr; |
| 6273 | | unsigned line = 0; |
| 6274 | | type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, |
| 6275 | | ZigLLVMTag_DW_structure_type(), buf_ptr(&type->name), |
| 6276 | | compile_unit_scope, di_file, line); |
| 6304 | type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, |
| 6305 | ZigLLVMTag_DW_structure_type(), buf_ptr(&type->name), |
| 6306 | compile_unit_scope, di_file, line); |
| 6307 | |
| 6308 | type->data.structure.resolve_status = ResolveStatusLLVMFwdDecl; |
| 6309 | if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return; |
| 6310 | } |
| 6277 | 6311 | |
| 6278 | 6312 | if (!type_has_bits(child_type)) { |
| 6279 | 6313 | LLVMTypeRef element_types[] = { |
| ... | ... | @@ -6304,6 +6338,7 @@ static void resolve_llvm_types_slice(CodeGen *g, ZigType *type) { |
| 6304 | 6338 | |
| 6305 | 6339 | ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type); |
| 6306 | 6340 | type->llvm_di_type = replacement_di_type; |
| 6341 | type->data.structure.resolve_status = ResolveStatusLLVMFull; |
| 6307 | 6342 | return; |
| 6308 | 6343 | } |
| 6309 | 6344 | |
| ... | ... | @@ -6345,17 +6380,16 @@ static void resolve_llvm_types_slice(CodeGen *g, ZigType *type) { |
| 6345 | 6380 | |
| 6346 | 6381 | ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type); |
| 6347 | 6382 | type->llvm_di_type = replacement_di_type; |
| 6383 | type->data.structure.resolve_status = ResolveStatusLLVMFull; |
| 6348 | 6384 | } |
| 6349 | 6385 | |
| 6350 | | static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) { |
| 6386 | static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveStatus wanted_resolve_status) { |
| 6351 | 6387 | assert(struct_type->id == ZigTypeIdStruct); |
| 6352 | 6388 | assert(struct_type->data.structure.resolve_status != ResolveStatusInvalid); |
| 6353 | 6389 | assert(struct_type->data.structure.resolve_status >= ResolveStatusSizeKnown); |
| 6354 | 6390 | assert(struct_type->data.structure.fields || struct_type->data.structure.src_field_count == 0); |
| 6391 | if (struct_type->data.structure.resolve_status >= wanted_resolve_status) return; |
| 6355 | 6392 | |
| 6356 | | // Do this early for the benefit of recursion. |
| 6357 | | struct_type->llvm_type = type_has_bits(struct_type) ? |
| 6358 | | LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&struct_type->name)) : LLVMVoidType(); |
| 6359 | 6393 | AstNode *decl_node = struct_type->data.structure.decl_node; |
| 6360 | 6394 | ZigLLVMDIFile *di_file; |
| 6361 | 6395 | ZigLLVMDIScope *di_scope; |
| ... | ... | @@ -6372,10 +6406,18 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) { |
| 6372 | 6406 | di_scope = ZigLLVMCompileUnitToScope(g->compile_unit); |
| 6373 | 6407 | line = 0; |
| 6374 | 6408 | } |
| 6375 | | unsigned dwarf_kind = ZigLLVMTag_DW_structure_type(); |
| 6376 | | struct_type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, |
| 6377 | | dwarf_kind, buf_ptr(&struct_type->name), |
| 6378 | | di_scope, di_file, line); |
| 6409 | |
| 6410 | if (struct_type->data.structure.resolve_status < ResolveStatusLLVMFwdDecl) { |
| 6411 | struct_type->llvm_type = type_has_bits(struct_type) ? |
| 6412 | LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&struct_type->name)) : LLVMVoidType(); |
| 6413 | unsigned dwarf_kind = ZigLLVMTag_DW_structure_type(); |
| 6414 | struct_type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, |
| 6415 | dwarf_kind, buf_ptr(&struct_type->name), |
| 6416 | di_scope, di_file, line); |
| 6417 | |
| 6418 | struct_type->data.structure.resolve_status = ResolveStatusLLVMFwdDecl; |
| 6419 | if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return; |
| 6420 | } |
| 6379 | 6421 | |
| 6380 | 6422 | size_t field_count = struct_type->data.structure.src_field_count; |
| 6381 | 6423 | size_t gen_field_count = struct_type->data.structure.gen_field_count; |
| ... | ... | @@ -6402,14 +6444,15 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) { |
| 6402 | 6444 | // this field is not byte-aligned; it is part of the previous field with a bit offset |
| 6403 | 6445 | |
| 6404 | 6446 | size_t full_bit_count = next_packed_bits_offset - first_packed_bits_offset_misalign; |
| 6405 | | if (get_store_size_in_bits(full_bit_count) == full_bit_count) { |
| 6406 | | // next field recovers store alignment |
| 6447 | size_t full_abi_size = get_abi_size_bytes(full_bit_count, g->pointer_size_bytes); |
| 6448 | if (full_abi_size * 8 == full_bit_count) { |
| 6449 | // next field recovers ABI alignment |
| 6407 | 6450 | element_types[gen_field_index] = LLVMIntType((unsigned)(full_bit_count)); |
| 6408 | 6451 | gen_field_index += 1; |
| 6409 | 6452 | |
| 6410 | 6453 | first_packed_bits_offset_misalign = SIZE_MAX; |
| 6411 | 6454 | } |
| 6412 | | } else if (get_store_size_in_bits(field_type->size_in_bits) != field_size_in_bits) { |
| 6455 | } else if (get_abi_size_bytes(field_type->size_in_bits, g->pointer_size_bytes) * 8 != field_size_in_bits) { |
| 6413 | 6456 | first_packed_bits_offset_misalign = packed_bits_offset; |
| 6414 | 6457 | } else { |
| 6415 | 6458 | // This is a byte-aligned field (both start and end) in a packed struct. |
| ... | ... | @@ -6426,8 +6469,8 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) { |
| 6426 | 6469 | } |
| 6427 | 6470 | if (first_packed_bits_offset_misalign != SIZE_MAX) { |
| 6428 | 6471 | size_t full_bit_count = packed_bits_offset - first_packed_bits_offset_misalign; |
| 6429 | | size_t store_bit_count = get_store_size_in_bits(full_bit_count); |
| 6430 | | element_types[gen_field_index] = LLVMIntType((unsigned)store_bit_count); |
| 6472 | size_t full_abi_size = get_abi_size_bytes(full_bit_count, g->pointer_size_bytes); |
| 6473 | element_types[gen_field_index] = LLVMIntType((unsigned)full_abi_size * 8); |
| 6431 | 6474 | gen_field_index += 1; |
| 6432 | 6475 | } |
| 6433 | 6476 | |
| ... | ... | @@ -6466,7 +6509,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) { |
| 6466 | 6509 | debug_align_in_bits = 8 * type_struct_field->type_entry->abi_align; |
| 6467 | 6510 | debug_offset_in_bits = 8 * type_struct_field->offset + type_struct_field->bit_offset_in_host; |
| 6468 | 6511 | } else { |
| 6469 | | debug_size_in_bits = get_store_size_in_bits(field_type->size_in_bits); |
| 6512 | debug_size_in_bits = 8 * get_store_size_bytes(field_type->size_in_bits); |
| 6470 | 6513 | debug_align_in_bits = 8 * field_type->abi_align; |
| 6471 | 6514 | debug_offset_in_bits = 8 * type_struct_field->offset; |
| 6472 | 6515 | } |
| ... | ... | @@ -6488,7 +6531,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) { |
| 6488 | 6531 | debug_field_index += 1; |
| 6489 | 6532 | } |
| 6490 | 6533 | |
| 6491 | | uint64_t debug_size_in_bits = get_store_size_in_bits(struct_type->size_in_bits); |
| 6534 | uint64_t debug_size_in_bits = 8*get_store_size_bytes(struct_type->size_in_bits); |
| 6492 | 6535 | uint64_t debug_align_in_bits = 8*struct_type->abi_align; |
| 6493 | 6536 | ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, |
| 6494 | 6537 | di_scope, |
| ... | ... | @@ -6500,11 +6543,13 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type) { |
| 6500 | 6543 | |
| 6501 | 6544 | ZigLLVMReplaceTemporary(g->dbuilder, struct_type->llvm_di_type, replacement_di_type); |
| 6502 | 6545 | struct_type->llvm_di_type = replacement_di_type; |
| 6546 | struct_type->data.structure.resolve_status = ResolveStatusLLVMFull; |
| 6503 | 6547 | } |
| 6504 | 6548 | |
| 6505 | 6549 | static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type) { |
| 6506 | 6550 | assert(!enum_type->data.enumeration.is_invalid); |
| 6507 | 6551 | assert(enum_type->data.enumeration.complete); |
| 6552 | if (enum_type->llvm_di_type != nullptr) return; |
| 6508 | 6553 | |
| 6509 | 6554 | uint32_t field_count = enum_type->data.enumeration.src_field_count; |
| 6510 | 6555 | |
| ... | ... | @@ -6541,27 +6586,34 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type) { |
| 6541 | 6586 | enum_type->llvm_type = get_llvm_type(g, tag_int_type); |
| 6542 | 6587 | } |
| 6543 | 6588 | |
| 6544 | | static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type) { |
| 6589 | static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveStatus wanted_resolve_status) { |
| 6590 | if (union_type->data.unionation.resolve_status >= wanted_resolve_status) return; |
| 6591 | |
| 6545 | 6592 | ZigType *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member; |
| 6546 | 6593 | ZigType *tag_type = union_type->data.unionation.tag_type; |
| 6547 | 6594 | if (most_aligned_union_member == nullptr) { |
| 6548 | 6595 | union_type->llvm_type = get_llvm_type(g, tag_type); |
| 6549 | 6596 | union_type->llvm_di_type = get_llvm_di_type(g, tag_type); |
| 6597 | union_type->data.unionation.resolve_status = ResolveStatusLLVMFull; |
| 6550 | 6598 | return; |
| 6551 | 6599 | } |
| 6552 | 6600 | |
| 6553 | | // Do this first for the benefit of recursive calls. |
| 6554 | | union_type->llvm_type = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&union_type->name)); |
| 6555 | 6601 | Scope *scope = &union_type->data.unionation.decls_scope->base; |
| 6556 | 6602 | ZigType *import = get_scope_import(scope); |
| 6557 | 6603 | AstNode *decl_node = union_type->data.unionation.decl_node; |
| 6558 | | size_t line = decl_node ? decl_node->line : 0; |
| 6559 | | unsigned dwarf_kind = ZigLLVMTag_DW_structure_type(); |
| 6560 | | union_type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, |
| 6561 | | dwarf_kind, buf_ptr(&union_type->name), |
| 6562 | | ZigLLVMFileToScope(import->data.structure.root_struct->di_file), |
| 6563 | | import->data.structure.root_struct->di_file, (unsigned)(line + 1)); |
| 6564 | 6604 | |
| 6605 | if (union_type->data.unionation.resolve_status < ResolveStatusLLVMFwdDecl) { |
| 6606 | union_type->llvm_type = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&union_type->name)); |
| 6607 | size_t line = decl_node ? decl_node->line : 0; |
| 6608 | unsigned dwarf_kind = ZigLLVMTag_DW_structure_type(); |
| 6609 | union_type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, |
| 6610 | dwarf_kind, buf_ptr(&union_type->name), |
| 6611 | ZigLLVMFileToScope(import->data.structure.root_struct->di_file), |
| 6612 | import->data.structure.root_struct->di_file, (unsigned)(line + 1)); |
| 6613 | |
| 6614 | union_type->data.unionation.resolve_status = ResolveStatusLLVMFwdDecl; |
| 6615 | if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return; |
| 6616 | } |
| 6565 | 6617 | |
| 6566 | 6618 | uint32_t gen_field_count = union_type->data.unionation.gen_field_count; |
| 6567 | 6619 | ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(gen_field_count); |
| ... | ... | @@ -6615,6 +6667,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type) { |
| 6615 | 6667 | |
| 6616 | 6668 | ZigLLVMReplaceTemporary(g->dbuilder, union_type->llvm_di_type, replacement_di_type); |
| 6617 | 6669 | union_type->llvm_di_type = replacement_di_type; |
| 6670 | union_type->data.unionation.resolve_status = ResolveStatusLLVMFull; |
| 6618 | 6671 | return; |
| 6619 | 6672 | } |
| 6620 | 6673 | |
| ... | ... | @@ -6685,9 +6738,12 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type) { |
| 6685 | 6738 | |
| 6686 | 6739 | ZigLLVMReplaceTemporary(g->dbuilder, union_type->llvm_di_type, replacement_di_type); |
| 6687 | 6740 | union_type->llvm_di_type = replacement_di_type; |
| 6741 | union_type->data.unionation.resolve_status = ResolveStatusLLVMFull; |
| 6688 | 6742 | } |
| 6689 | 6743 | |
| 6690 | 6744 | static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type) { |
| 6745 | if (type->llvm_di_type != nullptr) return; |
| 6746 | |
| 6691 | 6747 | ZigType *elem_type = type->data.pointer.child_type; |
| 6692 | 6748 | |
| 6693 | 6749 | if (type->data.pointer.is_const || type->data.pointer.is_volatile || |
| ... | ... | @@ -6702,10 +6758,11 @@ static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type) { |
| 6702 | 6758 | } |
| 6703 | 6759 | |
| 6704 | 6760 | if (type->data.pointer.host_int_bytes == 0) { |
| 6705 | | type->llvm_type = LLVMPointerType(get_llvm_type(g, elem_type), 0); |
| 6706 | | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, type->llvm_type); |
| 6707 | | uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, type->llvm_type); |
| 6708 | | type->llvm_di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, get_llvm_di_type(g, elem_type), |
| 6761 | assertNoError(type_resolve(g, elem_type, ResolveStatusLLVMFwdDecl)); |
| 6762 | type->llvm_type = LLVMPointerType(elem_type->llvm_type, 0); |
| 6763 | uint64_t debug_size_in_bits = 8*get_store_size_bytes(type->size_in_bits); |
| 6764 | uint64_t debug_align_in_bits = 8*type->abi_align; |
| 6765 | type->llvm_di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, elem_type->llvm_di_type, |
| 6709 | 6766 | debug_size_in_bits, debug_align_in_bits, buf_ptr(&type->name)); |
| 6710 | 6767 | } else { |
| 6711 | 6768 | ZigType *host_int_type = get_int_type(g, false, type->data.pointer.host_int_bytes * 8); |
| ... | ... | @@ -6719,6 +6776,8 @@ static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type) { |
| 6719 | 6776 | } |
| 6720 | 6777 | |
| 6721 | 6778 | static void resolve_llvm_types_integer(CodeGen *g, ZigType *type) { |
| 6779 | if (type->llvm_di_type != nullptr) return; |
| 6780 | |
| 6722 | 6781 | unsigned dwarf_tag; |
| 6723 | 6782 | if (type->data.integral.is_signed) { |
| 6724 | 6783 | if (type->size_in_bits == 8) { |
| ... | ... | @@ -6739,6 +6798,8 @@ static void resolve_llvm_types_integer(CodeGen *g, ZigType *type) { |
| 6739 | 6798 | } |
| 6740 | 6799 | |
| 6741 | 6800 | static void resolve_llvm_types_optional(CodeGen *g, ZigType *type) { |
| 6801 | if (type->llvm_di_type != nullptr) return; |
| 6802 | |
| 6742 | 6803 | LLVMTypeRef bool_llvm_type = get_llvm_type(g, g->builtin_types.entry_bool); |
| 6743 | 6804 | ZigLLVMDIType *bool_llvm_di_type = get_llvm_di_type(g, g->builtin_types.entry_bool); |
| 6744 | 6805 | |
| ... | ... | @@ -6807,6 +6868,8 @@ static void resolve_llvm_types_optional(CodeGen *g, ZigType *type) { |
| 6807 | 6868 | } |
| 6808 | 6869 | |
| 6809 | 6870 | static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) { |
| 6871 | if (type->llvm_di_type != nullptr) return; |
| 6872 | |
| 6810 | 6873 | ZigType *payload_type = type->data.error_union.payload_type; |
| 6811 | 6874 | ZigType *err_set_type = type->data.error_union.err_set_type; |
| 6812 | 6875 | |
| ... | ... | @@ -6874,6 +6937,8 @@ static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) { |
| 6874 | 6937 | } |
| 6875 | 6938 | |
| 6876 | 6939 | static void resolve_llvm_types_array(CodeGen *g, ZigType *type) { |
| 6940 | if (type->llvm_di_type != nullptr) return; |
| 6941 | |
| 6877 | 6942 | ZigType *elem_type = type->data.array.child_type; |
| 6878 | 6943 | |
| 6879 | 6944 | // TODO https://github.com/ziglang/zig/issues/1424 |
| ... | ... | @@ -6887,6 +6952,8 @@ static void resolve_llvm_types_array(CodeGen *g, ZigType *type) { |
| 6887 | 6952 | } |
| 6888 | 6953 | |
| 6889 | 6954 | static void resolve_llvm_types_fn(CodeGen *g, ZigType *fn_type) { |
| 6955 | if (fn_type->llvm_di_type != nullptr) return; |
| 6956 | |
| 6890 | 6957 | FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; |
| 6891 | 6958 | bool first_arg_return = want_first_arg_sret(g, fn_type_id); |
| 6892 | 6959 | bool is_async = fn_type_id->cc == CallingConventionAsync; |
| ... | ... | @@ -7010,16 +7077,12 @@ static void resolve_llvm_types_anyerror(CodeGen *g) { |
| 7010 | 7077 | get_llvm_di_type(g, g->err_tag_type), ""); |
| 7011 | 7078 | } |
| 7012 | 7079 | |
| 7013 | | static void resolve_llvm_types(CodeGen *g, ZigType *type) { |
| 7014 | | assert(type_is_resolved(type, ResolveStatusSizeKnown)); |
| 7080 | static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) { |
| 7081 | assert(type->id == ZigTypeIdOpaque || type_is_resolved(type, ResolveStatusSizeKnown)); |
| 7082 | assert(wanted_resolve_status > ResolveStatusSizeKnown); |
| 7015 | 7083 | switch (type->id) { |
| 7016 | 7084 | case ZigTypeIdInvalid: |
| 7017 | | case ZigTypeIdFloat: |
| 7018 | | case ZigTypeIdOpaque: |
| 7019 | 7085 | case ZigTypeIdMetaType: |
| 7020 | | case ZigTypeIdVoid: |
| 7021 | | case ZigTypeIdBool: |
| 7022 | | case ZigTypeIdUnreachable: |
| 7023 | 7086 | case ZigTypeIdComptimeFloat: |
| 7024 | 7087 | case ZigTypeIdComptimeInt: |
| 7025 | 7088 | case ZigTypeIdEnumLiteral: |
| ... | ... | @@ -7028,18 +7091,26 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type) { |
| 7028 | 7091 | case ZigTypeIdBoundFn: |
| 7029 | 7092 | case ZigTypeIdArgTuple: |
| 7030 | 7093 | zig_unreachable(); |
| 7094 | case ZigTypeIdFloat: |
| 7095 | case ZigTypeIdOpaque: |
| 7096 | case ZigTypeIdVoid: |
| 7097 | case ZigTypeIdBool: |
| 7098 | case ZigTypeIdUnreachable: |
| 7099 | assert(type->llvm_di_type != nullptr); |
| 7100 | return; |
| 7031 | 7101 | case ZigTypeIdStruct: |
| 7032 | 7102 | if (type->data.structure.is_slice) |
| 7033 | | return resolve_llvm_types_slice(g, type); |
| 7103 | return resolve_llvm_types_slice(g, type, wanted_resolve_status); |
| 7034 | 7104 | else |
| 7035 | | return resolve_llvm_types_struct(g, type); |
| 7105 | return resolve_llvm_types_struct(g, type, wanted_resolve_status); |
| 7036 | 7106 | case ZigTypeIdEnum: |
| 7037 | 7107 | return resolve_llvm_types_enum(g, type); |
| 7038 | 7108 | case ZigTypeIdUnion: |
| 7039 | | return resolve_llvm_types_union(g, type); |
| 7109 | return resolve_llvm_types_union(g, type, wanted_resolve_status); |
| 7040 | 7110 | case ZigTypeIdPointer: |
| 7041 | 7111 | return resolve_llvm_types_pointer(g, type); |
| 7042 | 7112 | case ZigTypeIdPromise: { |
| 7113 | if (type->llvm_di_type != nullptr) return; |
| 7043 | 7114 | ZigType *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, false); |
| 7044 | 7115 | type->llvm_type = get_llvm_type(g, u8_ptr_type); |
| 7045 | 7116 | type->llvm_di_type = get_llvm_di_type(g, u8_ptr_type); |
| ... | ... | @@ -7056,6 +7127,8 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type) { |
| 7056 | 7127 | case ZigTypeIdFn: |
| 7057 | 7128 | return resolve_llvm_types_fn(g, type); |
| 7058 | 7129 | case ZigTypeIdErrorSet: { |
| 7130 | if (type->llvm_di_type != nullptr) return; |
| 7131 | |
| 7059 | 7132 | if (g->builtin_types.entry_global_error_set->llvm_type == nullptr) { |
| 7060 | 7133 | resolve_llvm_types_anyerror(g); |
| 7061 | 7134 | } |
| ... | ... | @@ -7064,6 +7137,8 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type) { |
| 7064 | 7137 | return; |
| 7065 | 7138 | } |
| 7066 | 7139 | case ZigTypeIdVector: { |
| 7140 | if (type->llvm_di_type != nullptr) return; |
| 7141 | |
| 7067 | 7142 | type->llvm_type = LLVMVectorType(get_llvm_type(g, type->data.vector.elem_type), type->data.vector.len); |
| 7068 | 7143 | type->llvm_di_type = ZigLLVMDIBuilderCreateVectorType(g->dbuilder, type->size_in_bits, |
| 7069 | 7144 | type->abi_align, get_llvm_di_type(g, type->data.vector.elem_type), type->data.vector.len); |
| ... | ... | @@ -7074,23 +7149,13 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type) { |
| 7074 | 7149 | } |
| 7075 | 7150 | |
| 7076 | 7151 | LLVMTypeRef get_llvm_type(CodeGen *g, ZigType *type) { |
| 7077 | | if (type->llvm_type != nullptr) |
| 7078 | | return type->llvm_type; |
| 7079 | | resolve_llvm_types(g, type); |
| 7080 | | assert(type->llvm_type != nullptr); |
| 7081 | | assert(type->llvm_di_type != nullptr); |
| 7152 | assertNoError(type_resolve(g, type, ResolveStatusLLVMFull)); |
| 7082 | 7153 | assert(type->abi_size == 0 || type->abi_size == LLVMABISizeOfType(g->target_data_ref, type->llvm_type)); |
| 7083 | 7154 | assert(type->abi_align == 0 || type->abi_align == LLVMABIAlignmentOfType(g->target_data_ref, type->llvm_type)); |
| 7084 | 7155 | return type->llvm_type; |
| 7085 | 7156 | } |
| 7086 | 7157 | |
| 7087 | 7158 | ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type) { |
| 7088 | | if (type->llvm_di_type != nullptr) |
| 7089 | | return type->llvm_di_type; |
| 7090 | | resolve_llvm_types(g, type); |
| 7091 | | assert(type->llvm_type != nullptr); |
| 7092 | | assert(type->llvm_di_type != nullptr); |
| 7093 | | assert(type->abi_size == 0 || type->abi_size == LLVMABISizeOfType(g->target_data_ref, type->llvm_type)); |
| 7094 | | assert(type->abi_align == 0 || type->abi_align == LLVMABIAlignmentOfType(g->target_data_ref, type->llvm_type)); |
| 7159 | assertNoError(type_resolve(g, type, ResolveStatusLLVMFull)); |
| 7095 | 7160 | return type->llvm_di_type; |
| 7096 | 7161 | } |