| author | |
| committer | |
| log | 6504c5098ead851b369af0525c11ad2ea4cee8a2 |
| tree | 3eaa22acec3003b3dfc5965d9a475c63afbd23ce |
| parent | d5e788072d8b207334c0eab0f1289317a55c9344 |
| signature | Commit is signed but in an unrecognized format. |
6 files changed, 42 insertions(+), 23 deletions(-)
src/all_types.hpp+8-2| ... | ... | @@ -1308,6 +1308,13 @@ struct RootStruct { |
| 1308 | 1308 | ZigLLVMDIFile *di_file; |
| 1309 | 1309 | }; |
| 1310 | 1310 | |
| 1311 | enum StructSpecial { | |
| 1312 | StructSpecialNone, | |
| 1313 | StructSpecialSlice, | |
| 1314 | StructSpecialInferredTuple, | |
| 1315 | StructSpecialInferredStruct, | |
| 1316 | }; | |
| 1317 | ||
| 1311 | 1318 | struct ZigTypeStruct { |
| 1312 | 1319 | AstNode *decl_node; |
| 1313 | 1320 | TypeStructField **fields; |
| ... | ... | @@ -1323,13 +1330,12 @@ struct ZigTypeStruct { |
| 1323 | 1330 | ContainerLayout layout; |
| 1324 | 1331 | ResolveStatus resolve_status; |
| 1325 | 1332 | |
| 1326 | bool is_slice; | |
| 1333 | StructSpecial special; | |
| 1327 | 1334 | // whether any of the fields require comptime |
| 1328 | 1335 | // known after ResolveStatusZeroBitsKnown |
| 1329 | 1336 | bool requires_comptime; |
| 1330 | 1337 | bool resolve_loop_flag_zero_bits; |
| 1331 | 1338 | bool resolve_loop_flag_other; |
| 1332 | bool is_inferred; | |
| 1333 | 1339 | }; |
| 1334 | 1340 | |
| 1335 | 1341 | struct ZigTypeOptional { |
src/analyze.cpp+12-6| ... | ... | @@ -420,7 +420,7 @@ uint32_t get_abi_alignment(CodeGen *g, ZigType *type_entry) { |
| 420 | 420 | } |
| 421 | 421 | |
| 422 | 422 | static bool is_slice(ZigType *type) { |
| 423 | return type->id == ZigTypeIdStruct && type->data.structure.is_slice; | |
| 423 | return type->id == ZigTypeIdStruct && type->data.structure.special == StructSpecialSlice; | |
| 424 | 424 | } |
| 425 | 425 | |
| 426 | 426 | ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) { |
| ... | ... | @@ -832,7 +832,7 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) { |
| 832 | 832 | |
| 833 | 833 | entry->data.structure.resolve_status = ResolveStatusSizeKnown; |
| 834 | 834 | entry->data.structure.layout = ContainerLayoutAuto; |
| 835 | entry->data.structure.is_slice = true; | |
| 835 | entry->data.structure.special = StructSpecialSlice; | |
| 836 | 836 | entry->data.structure.src_field_count = element_count; |
| 837 | 837 | entry->data.structure.gen_field_count = element_count; |
| 838 | 838 | entry->data.structure.fields = alloc_type_struct_fields(element_count); |
| ... | ... | @@ -2752,7 +2752,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { |
| 2752 | 2752 | } else if (decl_node->type == NodeTypeContainerInitExpr) { |
| 2753 | 2753 | field_count = struct_type->data.structure.src_field_count; |
| 2754 | 2754 | |
| 2755 | src_assert(struct_type->data.structure.is_inferred, decl_node); | |
| 2755 | src_assert(is_anon_container(struct_type), decl_node); | |
| 2756 | 2756 | src_assert(field_count == 0 || struct_type->data.structure.fields != nullptr, decl_node); |
| 2757 | 2757 | } else zig_unreachable(); |
| 2758 | 2758 | |
| ... | ... | @@ -4256,7 +4256,7 @@ bool is_container(ZigType *type_entry) { |
| 4256 | 4256 | case ZigTypeIdInvalid: |
| 4257 | 4257 | zig_unreachable(); |
| 4258 | 4258 | case ZigTypeIdStruct: |
| 4259 | return !type_entry->data.structure.is_slice; | |
| 4259 | return type_entry->data.structure.special != StructSpecialSlice; | |
| 4260 | 4260 | case ZigTypeIdEnum: |
| 4261 | 4261 | case ZigTypeIdUnion: |
| 4262 | 4262 | return true; |
| ... | ... | @@ -7391,7 +7391,7 @@ size_t type_id_index(ZigType *entry) { |
| 7391 | 7391 | case ZigTypeIdArray: |
| 7392 | 7392 | return 7; |
| 7393 | 7393 | case ZigTypeIdStruct: |
| 7394 | if (entry->data.structure.is_slice) | |
| 7394 | if (entry->data.structure.special == StructSpecialSlice) | |
| 7395 | 7395 | return 6; |
| 7396 | 7396 | return 8; |
| 7397 | 7397 | case ZigTypeIdComptimeFloat: |
| ... | ... | @@ -9077,7 +9077,7 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r |
| 9077 | 9077 | assert(type->llvm_di_type != nullptr); |
| 9078 | 9078 | return; |
| 9079 | 9079 | case ZigTypeIdStruct: |
| 9080 | if (type->data.structure.is_slice) | |
| 9080 | if (type->data.structure.special == StructSpecialSlice) | |
| 9081 | 9081 | return resolve_llvm_types_slice(g, type, wanted_resolve_status); |
| 9082 | 9082 | else |
| 9083 | 9083 | return resolve_llvm_types_struct(g, type, wanted_resolve_status, nullptr); |
| ... | ... | @@ -9229,3 +9229,9 @@ void IrExecutable::src() { |
| 9229 | 9229 | it->source_node->src(); |
| 9230 | 9230 | } |
| 9231 | 9231 | } |
| 9232 | ||
| 9233 | bool is_anon_container(ZigType *ty) { | |
| 9234 | return ty->id == ZigTypeIdStruct && ( | |
| 9235 | ty->data.structure.special == StructSpecialInferredTuple || | |
| 9236 | ty->data.structure.special == StructSpecialInferredStruct); | |
| 9237 | } |
src/analyze.hpp+1| ... | ... | @@ -278,4 +278,5 @@ IrInstruction *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, |
| 278 | 278 | Error analyze_import(CodeGen *codegen, ZigType *source_import, Buf *import_target_str, |
| 279 | 279 | ZigType **out_import, Buf **out_import_target_path, Buf *out_full_path); |
| 280 | 280 | ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry); |
| 281 | bool is_anon_container(ZigType *ty); | |
| 281 | 282 | #endif |
src/codegen.cpp+7-5| ... | ... | @@ -2998,9 +2998,9 @@ static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutable *executable, |
| 2998 | 2998 | |
| 2999 | 2999 | LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); |
| 3000 | 3000 | assert(wanted_type->id == ZigTypeIdStruct); |
| 3001 | assert(wanted_type->data.structure.is_slice); | |
| 3001 | assert(wanted_type->data.structure.special == StructSpecialSlice); | |
| 3002 | 3002 | assert(actual_type->id == ZigTypeIdStruct); |
| 3003 | assert(actual_type->data.structure.is_slice); | |
| 3003 | assert(actual_type->data.structure.special == StructSpecialSlice); | |
| 3004 | 3004 | |
| 3005 | 3005 | ZigType *actual_pointer_type = actual_type->data.structure.fields[0]->type_entry; |
| 3006 | 3006 | ZigType *actual_child_type = actual_pointer_type->data.pointer.child_type; |
| ... | ... | @@ -3751,7 +3751,7 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI |
| 3751 | 3751 | return LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 1, ""); |
| 3752 | 3752 | } else if (array_type->id == ZigTypeIdStruct) { |
| 3753 | 3753 | LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type); |
| 3754 | assert(array_type->data.structure.is_slice); | |
| 3754 | assert(array_type->data.structure.special == StructSpecialSlice); | |
| 3755 | 3755 | |
| 3756 | 3756 | ZigType *ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry; |
| 3757 | 3757 | if (!type_has_bits(ptr_type)) { |
| ... | ... | @@ -5028,7 +5028,9 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I |
| 5028 | 5028 | { |
| 5029 | 5029 | align_bytes = target_type->data.maybe.child_type->data.fn.fn_type_id.alignment; |
| 5030 | 5030 | ptr_val = target_val; |
| 5031 | } else if (target_type->id == ZigTypeIdStruct && target_type->data.structure.is_slice) { | |
| 5031 | } else if (target_type->id == ZigTypeIdStruct && | |
| 5032 | target_type->data.structure.special == StructSpecialSlice) | |
| 5033 | { | |
| 5032 | 5034 | ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index]->type_entry; |
| 5033 | 5035 | align_bytes = get_ptr_align(g, slice_ptr_type); |
| 5034 | 5036 | |
| ... | ... | @@ -5290,7 +5292,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst |
| 5290 | 5292 | |
| 5291 | 5293 | return tmp_struct_ptr; |
| 5292 | 5294 | } else if (array_type->id == ZigTypeIdStruct) { |
| 5293 | assert(array_type->data.structure.is_slice); | |
| 5295 | assert(array_type->data.structure.special == StructSpecialSlice); | |
| 5294 | 5296 | assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind); |
| 5295 | 5297 | assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind); |
| 5296 | 5298 | assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(tmp_struct_ptr))) == LLVMStructTypeKind); |
src/dump_analysis.cpp+1-1| ... | ... | @@ -744,7 +744,7 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) { |
| 744 | 744 | case ZigTypeIdEnumLiteral: |
| 745 | 745 | break; |
| 746 | 746 | case ZigTypeIdStruct: { |
| 747 | if (ty->data.structure.is_slice) { | |
| 747 | if (ty->data.structure.special == StructSpecialSlice) { | |
| 748 | 748 | jw_object_field(jw, "len"); |
| 749 | 749 | jw_int(jw, 2); |
| 750 | 750 | anal_dump_pointer_attrs(ctx, ty->data.structure.fields[slice_ptr_index]->type_entry); |
src/ir.cpp+13-9| ... | ... | @@ -724,14 +724,11 @@ static bool is_opt_err_set(ZigType *ty) { |
| 724 | 724 | } |
| 725 | 725 | |
| 726 | 726 | static bool is_tuple(ZigType *type) { |
| 727 | return type->id == ZigTypeIdStruct && type->data.structure.decl_node != nullptr && | |
| 728 | type->data.structure.decl_node->type == NodeTypeContainerInitExpr && | |
| 729 | (type->data.structure.decl_node->data.container_init_expr.kind == ContainerInitKindArray || | |
| 730 | type->data.structure.decl_node->data.container_init_expr.entries.length == 0); | |
| 727 | return type->id == ZigTypeIdStruct && type->data.structure.special == StructSpecialInferredTuple; | |
| 731 | 728 | } |
| 732 | 729 | |
| 733 | 730 | static bool is_slice(ZigType *type) { |
| 734 | return type->id == ZigTypeIdStruct && type->data.structure.is_slice; | |
| 731 | return type->id == ZigTypeIdStruct && type->data.structure.special == StructSpecialSlice; | |
| 735 | 732 | } |
| 736 | 733 | |
| 737 | 734 | static bool slice_is_const(ZigType *type) { |
| ... | ... | @@ -13928,7 +13925,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 13928 | 13925 | } |
| 13929 | 13926 | |
| 13930 | 13927 | // cast from inferred struct type to array, union, or struct |
| 13931 | if (actual_type->id == ZigTypeIdStruct && actual_type->data.structure.is_inferred) { | |
| 13928 | if (is_anon_container(actual_type)) { | |
| 13932 | 13929 | AstNode *decl_node = actual_type->data.structure.decl_node; |
| 13933 | 13930 | ir_assert(decl_node->type == NodeTypeContainerInitExpr, source_instr); |
| 13934 | 13931 | ContainerInitKind init_kind = decl_node->data.container_init_expr.kind; |
| ... | ... | @@ -17047,10 +17044,17 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, |
| 17047 | 17044 | Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct), |
| 17048 | 17045 | instruction->base.scope, instruction->base.source_node, bare_name); |
| 17049 | 17046 | |
| 17047 | StructSpecial struct_special = StructSpecialInferredStruct; | |
| 17048 | if (instruction->base.source_node->type == NodeTypeContainerInitExpr && | |
| 17049 | instruction->base.source_node->data.container_init_expr.kind == ContainerInitKindArray) | |
| 17050 | { | |
| 17051 | struct_special = StructSpecialInferredTuple; | |
| 17052 | } | |
| 17053 | ||
| 17050 | 17054 | ZigType *inferred_struct_type = get_partial_container_type(ira->codegen, |
| 17051 | 17055 | instruction->base.scope, ContainerKindStruct, instruction->base.source_node, |
| 17052 | 17056 | buf_ptr(name), bare_name, ContainerLayoutAuto); |
| 17053 | inferred_struct_type->data.structure.is_inferred = true; | |
| 17057 | inferred_struct_type->data.structure.special = struct_special; | |
| 17054 | 17058 | inferred_struct_type->data.structure.resolve_status = ResolveStatusBeingInferred; |
| 17055 | 17059 | implicit_elem_type = inferred_struct_type; |
| 17056 | 17060 | } |
| ... | ... | @@ -19570,7 +19574,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction |
| 19570 | 19574 | bool is_const = struct_ptr->value->type->data.pointer.is_const; |
| 19571 | 19575 | bool is_volatile = struct_ptr->value->type->data.pointer.is_volatile; |
| 19572 | 19576 | ZigType *ptr_type; |
| 19573 | if (struct_type->data.structure.is_inferred) { | |
| 19577 | if (is_anon_container(struct_type)) { | |
| 19574 | 19578 | ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, |
| 19575 | 19579 | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 19576 | 19580 | } else { |
| ... | ... | @@ -22816,7 +22820,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 22816 | 22820 | } |
| 22817 | 22821 | case ZigTypeIdStruct: |
| 22818 | 22822 | { |
| 22819 | if (type_entry->data.structure.is_slice) { | |
| 22823 | if (type_entry->data.structure.special == StructSpecialSlice) { | |
| 22820 | 22824 | result = create_ptr_like_type_info(ira, type_entry); |
| 22821 | 22825 | if (result == nullptr) |
| 22822 | 22826 | return ErrorSemanticAnalyzeFail; |