| ... | @@ -1325,7 +1325,7 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt | ... | @@ -1325,7 +1325,7 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt |
| 1325 | | 1325 | |
| 1326 | uint32_t field_count = decl_node->data.struct_decl.fields.length; | 1326 | uint32_t field_count = decl_node->data.struct_decl.fields.length; |
| 1327 | | 1327 | |
| 1328 | enum_type->data.enumeration.field_count = field_count; | 1328 | enum_type->data.enumeration.src_field_count = field_count; |
| 1329 | enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); | 1329 | enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); |
| 1330 | ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count); | 1330 | ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count); |
| 1331 | | 1331 | |
| ... | @@ -2451,8 +2451,8 @@ static LabelTableEntry *find_label(CodeGen *g, BlockContext *orig_context, Buf * | ... | @@ -2451,8 +2451,8 @@ static LabelTableEntry *find_label(CodeGen *g, BlockContext *orig_context, Buf * |
| 2451 | return nullptr; | 2451 | return nullptr; |
| 2452 | } | 2452 | } |
| 2453 | | 2453 | |
| 2454 | static TypeEnumField *get_enum_field(TypeTableEntry *enum_type, Buf *name) { | 2454 | static TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name) { |
| 2455 | for (uint32_t i = 0; i < enum_type->data.enumeration.field_count; i += 1) { | 2455 | for (uint32_t i = 0; i < enum_type->data.enumeration.src_field_count; i += 1) { |
| 2456 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; | 2456 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; |
| 2457 | if (buf_eql_buf(type_enum_field->name, name)) { | 2457 | if (buf_eql_buf(type_enum_field->name, name)) { |
| 2458 | return type_enum_field; | 2458 | return type_enum_field; |
| ... | @@ -2467,7 +2467,7 @@ static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *imp | ... | @@ -2467,7 +2467,7 @@ static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *imp |
| 2467 | { | 2467 | { |
| 2468 | assert(field_access_node->type == NodeTypeFieldAccessExpr); | 2468 | assert(field_access_node->type == NodeTypeFieldAccessExpr); |
| 2469 | | 2469 | |
| 2470 | TypeEnumField *type_enum_field = get_enum_field(enum_type, field_name); | 2470 | TypeEnumField *type_enum_field = find_enum_type_field(enum_type, field_name); |
| 2471 | if (type_enum_field->type_entry->id == TypeTableEntryIdInvalid) { | 2471 | if (type_enum_field->type_entry->id == TypeTableEntryIdInvalid) { |
| 2472 | return g->builtin_types.entry_invalid; | 2472 | return g->builtin_types.entry_invalid; |
| 2473 | } | 2473 | } |
| ... | @@ -2715,6 +2715,41 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry | ... | @@ -2715,6 +2715,41 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry |
| 2715 | } | 2715 | } |
| 2716 | } | 2716 | } |
| 2717 | | 2717 | |
| | 2718 | static TypeTableEntry *analyze_member_access(CodeGen *g, bool wrapped_in_fn_call, |
| | 2719 | TypeTableEntry *bare_struct_type, Buf *field_name, AstNode *node, TypeTableEntry *struct_type) |
| | 2720 | { |
| | 2721 | assert(node->type == NodeTypeFieldAccessExpr); |
| | 2722 | if (wrapped_in_fn_call && !is_slice(bare_struct_type)) { |
| | 2723 | BlockContext *container_block_context = get_container_block_context(bare_struct_type); |
| | 2724 | assert(container_block_context); |
| | 2725 | auto entry = container_block_context->decl_table.maybe_get(field_name); |
| | 2726 | AstNode *fn_decl_node = entry ? entry->value : nullptr; |
| | 2727 | if (fn_decl_node && fn_decl_node->type == NodeTypeFnProto) { |
| | 2728 | resolve_top_level_decl(g, fn_decl_node, false); |
| | 2729 | TopLevelDecl *tld = get_as_top_level_decl(fn_decl_node); |
| | 2730 | if (tld->resolution == TldResolutionInvalid) { |
| | 2731 | return g->builtin_types.entry_invalid; |
| | 2732 | } |
| | 2733 | |
| | 2734 | node->data.field_access_expr.is_member_fn = true; |
| | 2735 | FnTableEntry *fn_entry = fn_decl_node->data.fn_proto.fn_table_entry; |
| | 2736 | if (fn_entry->type_entry->id == TypeTableEntryIdGenericFn) { |
| | 2737 | return resolve_expr_const_val_as_generic_fn(g, node, fn_entry->type_entry, false); |
| | 2738 | } else { |
| | 2739 | return resolve_expr_const_val_as_fn(g, node, fn_entry, false); |
| | 2740 | } |
| | 2741 | } else { |
| | 2742 | add_node_error(g, node, buf_sprintf("no function named '%s' in '%s'", |
| | 2743 | buf_ptr(field_name), buf_ptr(&bare_struct_type->name))); |
| | 2744 | return g->builtin_types.entry_invalid; |
| | 2745 | } |
| | 2746 | } else { |
| | 2747 | add_node_error(g, node, |
| | 2748 | buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), buf_ptr(&struct_type->name))); |
| | 2749 | return g->builtin_types.entry_invalid; |
| | 2750 | } |
| | 2751 | } |
| | 2752 | |
| 2718 | static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 2753 | static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 2719 | TypeTableEntry *expected_type, AstNode *node) | 2754 | TypeTableEntry *expected_type, AstNode *node) |
| 2720 | { | 2755 | { |
| ... | @@ -2742,34 +2777,28 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i | ... | @@ -2742,34 +2777,28 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i |
| 2742 | node->data.field_access_expr.type_struct_field = find_struct_type_field(bare_struct_type, field_name); | 2777 | node->data.field_access_expr.type_struct_field = find_struct_type_field(bare_struct_type, field_name); |
| 2743 | if (node->data.field_access_expr.type_struct_field) { | 2778 | if (node->data.field_access_expr.type_struct_field) { |
| 2744 | return node->data.field_access_expr.type_struct_field->type_entry; | 2779 | return node->data.field_access_expr.type_struct_field->type_entry; |
| 2745 | } else if (wrapped_in_fn_call && !is_slice(bare_struct_type)) { | 2780 | } else { |
| 2746 | BlockContext *container_block_context = get_container_block_context(bare_struct_type); | 2781 | return analyze_member_access(g, wrapped_in_fn_call, bare_struct_type, field_name, |
| 2747 | assert(container_block_context); | 2782 | node, struct_type); |
| 2748 | auto entry = container_block_context->decl_table.maybe_get(field_name); | 2783 | } |
| 2749 | AstNode *fn_decl_node = entry ? entry->value : nullptr; | 2784 | } else if (struct_type->id == TypeTableEntryIdEnum || (struct_type->id == TypeTableEntryIdPointer && |
| 2750 | if (fn_decl_node && fn_decl_node->type == NodeTypeFnProto) { | 2785 | struct_type->data.pointer.child_type->id == TypeTableEntryIdEnum)) |
| 2751 | resolve_top_level_decl(g, fn_decl_node, false); | 2786 | { |
| 2752 | TopLevelDecl *tld = get_as_top_level_decl(fn_decl_node); | 2787 | TypeTableEntry *bare_struct_type = (struct_type->id == TypeTableEntryIdEnum) ? |
| 2753 | if (tld->resolution == TldResolutionInvalid) { | 2788 | struct_type : struct_type->data.pointer.child_type; |
| 2754 | return g->builtin_types.entry_invalid; | | |
| 2755 | } | | |
| 2756 | | 2789 | |
| 2757 | node->data.field_access_expr.is_member_fn = true; | 2790 | if (!bare_struct_type->data.enumeration.complete) { |
| 2758 | FnTableEntry *fn_entry = fn_decl_node->data.fn_proto.fn_table_entry; | 2791 | resolve_struct_type(g, bare_struct_type->data.enumeration.decl_node->owner, bare_struct_type); |
| 2759 | if (fn_entry->type_entry->id == TypeTableEntryIdGenericFn) { | 2792 | } |
| 2760 | return resolve_expr_const_val_as_generic_fn(g, node, fn_entry->type_entry, false); | 2793 | |
| 2761 | } else { | 2794 | node->data.field_access_expr.bare_struct_type = bare_struct_type; |
| 2762 | return resolve_expr_const_val_as_fn(g, node, fn_entry, false); | 2795 | node->data.field_access_expr.type_enum_field = find_enum_type_field(bare_struct_type, field_name); |
| 2763 | } | 2796 | |
| 2764 | } else { | 2797 | if (node->data.field_access_expr.type_enum_field) { |
| 2765 | add_node_error(g, node, buf_sprintf("no function named '%s' in '%s'", | 2798 | return node->data.field_access_expr.type_enum_field->type_entry; |
| 2766 | buf_ptr(field_name), buf_ptr(&bare_struct_type->name))); | | |
| 2767 | return g->builtin_types.entry_invalid; | | |
| 2768 | } | | |
| 2769 | } else { | 2799 | } else { |
| 2770 | add_node_error(g, node, | 2800 | return analyze_member_access(g, wrapped_in_fn_call, bare_struct_type, field_name, |
| 2771 | buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), buf_ptr(&struct_type->name))); | 2801 | node, struct_type); |
| 2772 | return g->builtin_types.entry_invalid; | | |
| 2773 | } | 2802 | } |
| 2774 | } else if (struct_type->id == TypeTableEntryIdArray) { | 2803 | } else if (struct_type->id == TypeTableEntryIdArray) { |
| 2775 | if (buf_eql_str(field_name, "len")) { | 2804 | if (buf_eql_str(field_name, "len")) { |
| ... | @@ -5269,7 +5298,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry | ... | @@ -5269,7 +5298,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry |
| 5269 | if (type_entry->id == TypeTableEntryIdInvalid) { | 5298 | if (type_entry->id == TypeTableEntryIdInvalid) { |
| 5270 | return type_entry; | 5299 | return type_entry; |
| 5271 | } else if (type_entry->id == TypeTableEntryIdEnum) { | 5300 | } else if (type_entry->id == TypeTableEntryIdEnum) { |
| 5272 | uint64_t value_count = type_entry->data.enumeration.field_count; | 5301 | uint64_t value_count = type_entry->data.enumeration.src_field_count; |
| 5273 | return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type, | 5302 | return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type, |
| 5274 | value_count, false); | 5303 | value_count, false); |
| 5275 | } else { | 5304 | } else { |
| ... | @@ -6130,7 +6159,7 @@ static TypeTableEntry *analyze_switch_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -6130,7 +6159,7 @@ static TypeTableEntry *analyze_switch_expr(CodeGen *g, ImportTableEntry *import, |
| 6130 | size_t *field_use_counts = nullptr; | 6159 | size_t *field_use_counts = nullptr; |
| 6131 | HashMap<int, AstNode *, int_hash, int_eq> err_use_nodes = {}; | 6160 | HashMap<int, AstNode *, int_hash, int_eq> err_use_nodes = {}; |
| 6132 | if (expr_type->id == TypeTableEntryIdEnum) { | 6161 | if (expr_type->id == TypeTableEntryIdEnum) { |
| 6133 | field_use_counts = allocate<size_t>(expr_type->data.enumeration.field_count); | 6162 | field_use_counts = allocate<size_t>(expr_type->data.enumeration.src_field_count); |
| 6134 | } else if (expr_type->id == TypeTableEntryIdErrorUnion) { | 6163 | } else if (expr_type->id == TypeTableEntryIdErrorUnion) { |
| 6135 | err_use_nodes.init(10); | 6164 | err_use_nodes.init(10); |
| 6136 | } | 6165 | } |
| ... | @@ -6168,7 +6197,7 @@ static TypeTableEntry *analyze_switch_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -6168,7 +6197,7 @@ static TypeTableEntry *analyze_switch_expr(CodeGen *g, ImportTableEntry *import, |
| 6168 | if (expr_type->id == TypeTableEntryIdEnum) { | 6197 | if (expr_type->id == TypeTableEntryIdEnum) { |
| 6169 | if (item_node->type == NodeTypeSymbol) { | 6198 | if (item_node->type == NodeTypeSymbol) { |
| 6170 | Buf *field_name = item_node->data.symbol_expr.symbol; | 6199 | Buf *field_name = item_node->data.symbol_expr.symbol; |
| 6171 | TypeEnumField *type_enum_field = get_enum_field(expr_type, field_name); | 6200 | TypeEnumField *type_enum_field = find_enum_type_field(expr_type, field_name); |
| 6172 | if (type_enum_field) { | 6201 | if (type_enum_field) { |
| 6173 | item_node->data.symbol_expr.enum_field = type_enum_field; | 6202 | item_node->data.symbol_expr.enum_field = type_enum_field; |
| 6174 | if (!var_type) { | 6203 | if (!var_type) { |
| ... | @@ -6300,7 +6329,7 @@ static TypeTableEntry *analyze_switch_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -6300,7 +6329,7 @@ static TypeTableEntry *analyze_switch_expr(CodeGen *g, ImportTableEntry *import, |
| 6300 | } | 6329 | } |
| 6301 | | 6330 | |
| 6302 | if (expr_type->id == TypeTableEntryIdEnum && !else_prong) { | 6331 | if (expr_type->id == TypeTableEntryIdEnum && !else_prong) { |
| 6303 | for (uint32_t i = 0; i < expr_type->data.enumeration.field_count; i += 1) { | 6332 | for (uint32_t i = 0; i < expr_type->data.enumeration.src_field_count; i += 1) { |
| 6304 | if (field_use_counts[i] == 0) { | 6333 | if (field_use_counts[i] == 0) { |
| 6305 | add_node_error(g, node, | 6334 | add_node_error(g, node, |
| 6306 | buf_sprintf("enumeration value '%s' not handled in switch", | 6335 | buf_sprintf("enumeration value '%s' not handled in switch", |