| ... | @@ -189,6 +189,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFnTest *) { | ... | @@ -189,6 +189,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFnTest *) { |
| 189 | return IrInstructionIdSetFnTest; | 189 | return IrInstructionIdSetFnTest; |
| 190 | } | 190 | } |
| 191 | | 191 | |
| | 192 | static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayType *) { |
| | 193 | return IrInstructionIdArrayType; |
| | 194 | } |
| | 195 | |
| | 196 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceType *) { |
| | 197 | return IrInstructionIdSliceType; |
| | 198 | } |
| | 199 | |
| 192 | template<typename T> | 200 | template<typename T> |
| 193 | static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) { | 201 | static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) { |
| 194 | T *special_instruction = allocate<T>(1); | 202 | T *special_instruction = allocate<T>(1); |
| ... | @@ -716,19 +724,30 @@ static IrInstruction *ir_build_set_fn_test(IrBuilder *irb, AstNode *source_node, | ... | @@ -716,19 +724,30 @@ static IrInstruction *ir_build_set_fn_test(IrBuilder *irb, AstNode *source_node, |
| 716 | return &instruction->base; | 724 | return &instruction->base; |
| 717 | } | 725 | } |
| 718 | | 726 | |
| 719 | //static size_t get_conditional_defer_count(BlockContext *inner_block, BlockContext *outer_block) { | 727 | static IrInstruction *ir_build_array_type(IrBuilder *irb, AstNode *source_node, IrInstruction *size, |
| 720 | // size_t result = 0; | 728 | IrInstruction *child_type) |
| 721 | // while (inner_block != outer_block) { | 729 | { |
| 722 | // if (inner_block->node->type == NodeTypeDefer && | 730 | IrInstructionArrayType *instruction = ir_build_instruction<IrInstructionArrayType>(irb, source_node); |
| 723 | // (inner_block->node->data.defer.kind == ReturnKindError || | 731 | instruction->size = size; |
| 724 | // inner_block->node->data.defer.kind == ReturnKindMaybe)) | 732 | instruction->child_type = child_type; |
| 725 | // { | 733 | |
| 726 | // result += 1; | 734 | ir_ref_instruction(size); |
| 727 | // } | 735 | ir_ref_instruction(child_type); |
| 728 | // inner_block = inner_block->parent; | 736 | |
| 729 | // } | 737 | return &instruction->base; |
| 730 | // return result; | 738 | } |
| 731 | //} | 739 | |
| | 740 | static IrInstruction *ir_build_slice_type(IrBuilder *irb, AstNode *source_node, bool is_const, |
| | 741 | IrInstruction *child_type) |
| | 742 | { |
| | 743 | IrInstructionSliceType *instruction = ir_build_instruction<IrInstructionSliceType>(irb, source_node); |
| | 744 | instruction->is_const = is_const; |
| | 745 | instruction->child_type = child_type; |
| | 746 | |
| | 747 | ir_ref_instruction(child_type); |
| | 748 | |
| | 749 | return &instruction->base; |
| | 750 | } |
| 732 | | 751 | |
| 733 | static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, BlockContext *outer_block, | 752 | static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, BlockContext *outer_block, |
| 734 | bool gen_error_defers, bool gen_maybe_defers) | 753 | bool gen_error_defers, bool gen_maybe_defers) |
| ... | @@ -777,23 +796,6 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *node) { | ... | @@ -777,23 +796,6 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *node) { |
| 777 | zig_unreachable(); | 796 | zig_unreachable(); |
| 778 | } | 797 | } |
| 779 | | 798 | |
| 780 | //static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *source_node, IrInstruction *value, ReturnKnowledge rk) { | | |
| 781 | // BlockContext *defer_inner_block = source_node->block_context; | | |
| 782 | // BlockContext *defer_outer_block = irb->node->block_context; | | |
| 783 | // if (rk == ReturnKnowledgeUnknown) { | | |
| 784 | // if (get_conditional_defer_count(defer_inner_block, defer_outer_block) > 0) { | | |
| 785 | // // generate branching code that checks the return value and generates defers | | |
| 786 | // // if the return value is error | | |
| 787 | // zig_panic("TODO"); | | |
| 788 | // } | | |
| 789 | // } else if (rk != ReturnKnowledgeSkipDefers) { | | |
| 790 | // ir_gen_defers_for_block(irb, defer_inner_block, defer_outer_block, | | |
| 791 | // rk == ReturnKnowledgeKnownError, rk == ReturnKnowledgeKnownNull); | | |
| 792 | // } | | |
| 793 | // | | |
| 794 | // return ir_build_return(irb, source_node, value); | | |
| 795 | //} | | |
| 796 | | | |
| 797 | static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { | 799 | static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { |
| 798 | assert(basic_block); | 800 | assert(basic_block); |
| 799 | | 801 | |
| ... | @@ -1588,6 +1590,38 @@ static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, AstNode *node) { | ... | @@ -1588,6 +1590,38 @@ static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, AstNode *node) { |
| 1588 | return ir_build_const_bool(irb, node, node->data.bool_literal.value); | 1590 | return ir_build_const_bool(irb, node, node->data.bool_literal.value); |
| 1589 | } | 1591 | } |
| 1590 | | 1592 | |
| | 1593 | static IrInstruction *ir_gen_array_type(IrBuilder *irb, AstNode *node) { |
| | 1594 | assert(node->type == NodeTypeArrayType); |
| | 1595 | |
| | 1596 | AstNode *size_node = node->data.array_type.size; |
| | 1597 | AstNode *child_type_node = node->data.array_type.child_type; |
| | 1598 | bool is_const = node->data.array_type.is_const; |
| | 1599 | |
| | 1600 | if (size_node) { |
| | 1601 | if (is_const) { |
| | 1602 | add_node_error(irb->codegen, node, buf_create_from_str("const qualifier invalid on array type")); |
| | 1603 | return irb->codegen->invalid_instruction; |
| | 1604 | } |
| | 1605 | |
| | 1606 | IrInstruction *size_value = ir_gen_node(irb, size_node, node->block_context); |
| | 1607 | if (size_value == irb->codegen->invalid_instruction) |
| | 1608 | return size_value; |
| | 1609 | |
| | 1610 | IrInstruction *child_type = ir_gen_node(irb, child_type_node, node->block_context); |
| | 1611 | if (child_type == irb->codegen->invalid_instruction) |
| | 1612 | return child_type; |
| | 1613 | |
| | 1614 | return ir_build_array_type(irb, node, size_value, child_type); |
| | 1615 | } else { |
| | 1616 | IrInstruction *child_type = ir_gen_node_extra(irb, child_type_node, |
| | 1617 | node->block_context, LValPurposeAddressOf); |
| | 1618 | if (child_type == irb->codegen->invalid_instruction) |
| | 1619 | return child_type; |
| | 1620 | |
| | 1621 | return ir_build_slice_type(irb, node, is_const, child_type); |
| | 1622 | } |
| | 1623 | } |
| | 1624 | |
| 1591 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockContext *block_context, | 1625 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockContext *block_context, |
| 1592 | LValPurpose lval) | 1626 | LValPurpose lval) |
| 1593 | { | 1627 | { |
| ... | @@ -1627,6 +1661,8 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont | ... | @@ -1627,6 +1661,8 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont |
| 1627 | return ir_gen_this_literal(irb, node); | 1661 | return ir_gen_this_literal(irb, node); |
| 1628 | case NodeTypeBoolLiteral: | 1662 | case NodeTypeBoolLiteral: |
| 1629 | return ir_gen_bool_literal(irb, node); | 1663 | return ir_gen_bool_literal(irb, node); |
| | 1664 | case NodeTypeArrayType: |
| | 1665 | return ir_gen_array_type(irb, node); |
| 1630 | case NodeTypeUnwrapErrorExpr: | 1666 | case NodeTypeUnwrapErrorExpr: |
| 1631 | case NodeTypeDefer: | 1667 | case NodeTypeDefer: |
| 1632 | case NodeTypeSliceExpr: | 1668 | case NodeTypeSliceExpr: |
| ... | @@ -1644,7 +1680,6 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont | ... | @@ -1644,7 +1680,6 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont |
| 1644 | case NodeTypeZeroesLiteral: | 1680 | case NodeTypeZeroesLiteral: |
| 1645 | case NodeTypeErrorType: | 1681 | case NodeTypeErrorType: |
| 1646 | case NodeTypeTypeLiteral: | 1682 | case NodeTypeTypeLiteral: |
| 1647 | case NodeTypeArrayType: | | |
| 1648 | case NodeTypeVarLiteral: | 1683 | case NodeTypeVarLiteral: |
| 1649 | case NodeTypeRoot: | 1684 | case NodeTypeRoot: |
| 1650 | case NodeTypeFnProto: | 1685 | case NodeTypeFnProto: |
| ... | @@ -1703,51 +1738,6 @@ IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) { | ... | @@ -1703,51 +1738,6 @@ IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) { |
| 1703 | return ir_gen(codegn, body_node, scope, ir_executable); | 1738 | return ir_gen(codegn, body_node, scope, ir_executable); |
| 1704 | } | 1739 | } |
| 1705 | | 1740 | |
| 1706 | /* | | |
| 1707 | static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *node) { | | |
| 1708 | assert(node->type == NodeTypeGoto); | | |
| 1709 | Buf *label_name = node->data.goto_expr.name; | | |
| 1710 | BlockContext *context = node->block_context; | | |
| 1711 | assert(context); | | |
| 1712 | LabelTableEntry *label = find_label(g, context, label_name); | | |
| 1713 | | | |
| 1714 | if (!label) { | | |
| 1715 | add_node_error(g, node, buf_sprintf("no label in scope named '%s'", buf_ptr(label_name))); | | |
| 1716 | return; | | |
| 1717 | } | | |
| 1718 | | | |
| 1719 | label->used = true; | | |
| 1720 | node->data.goto_expr.label_entry = label; | | |
| 1721 | } | | |
| 1722 | | | |
| 1723 | for (size_t i = 0; i < fn_table_entry->goto_list.length; i += 1) { | | |
| 1724 | AstNode *goto_node = fn_table_entry->goto_list.at(i); | | |
| 1725 | assert(goto_node->type == NodeTypeGoto); | | |
| 1726 | analyze_goto_pass2(g, import, goto_node); | | |
| 1727 | } | | |
| 1728 | | | |
| 1729 | for (size_t i = 0; i < fn_table_entry->all_labels.length; i += 1) { | | |
| 1730 | LabelTableEntry *label = fn_table_entry->all_labels.at(i); | | |
| 1731 | if (!label->used) { | | |
| 1732 | add_node_error(g, label->decl_node, | | |
| 1733 | buf_sprintf("label '%s' defined but not used", | | |
| 1734 | buf_ptr(label->decl_node->data.label.name))); | | |
| 1735 | } | | |
| 1736 | } | | |
| 1737 | */ | | |
| 1738 | | | |
| 1739 | //static LabelTableEntry *find_label(CodeGen *g, BlockContext *orig_context, Buf *name) { | | |
| 1740 | // BlockContext *context = orig_context; | | |
| 1741 | // while (context && context->fn_entry) { | | |
| 1742 | // auto entry = context->label_table.maybe_get(name); | | |
| 1743 | // if (entry) { | | |
| 1744 | // return entry->value; | | |
| 1745 | // } | | |
| 1746 | // context = context->parent; | | |
| 1747 | // } | | |
| 1748 | // return nullptr; | | |
| 1749 | //} | | |
| 1750 | | | |
| 1751 | static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *other_type) { | 1741 | static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *other_type) { |
| 1752 | TypeTableEntry *other_type_underlying = get_underlying_type(other_type); | 1742 | TypeTableEntry *other_type_underlying = get_underlying_type(other_type); |
| 1753 | | 1743 | |
| ... | @@ -2970,6 +2960,59 @@ static TypeTableEntry *ir_analyze_unary_bool_not(IrAnalyze *ira, IrInstructionUn | ... | @@ -2970,6 +2960,59 @@ static TypeTableEntry *ir_analyze_unary_bool_not(IrAnalyze *ira, IrInstructionUn |
| 2970 | return bool_type; | 2960 | return bool_type; |
| 2971 | } | 2961 | } |
| 2972 | | 2962 | |
| | 2963 | static TypeTableEntry *ir_analyze_unary_prefix_op_err(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { |
| | 2964 | assert(un_op_instruction->op_id == IrUnOpError); |
| | 2965 | IrInstruction *value = un_op_instruction->value->other; |
| | 2966 | |
| | 2967 | TypeTableEntry *type_entry = value->type_entry; |
| | 2968 | if (type_entry->id == TypeTableEntryIdInvalid) |
| | 2969 | return ira->codegen->builtin_types.entry_invalid; |
| | 2970 | |
| | 2971 | TypeTableEntry *meta_type = ir_resolve_type(ira, value); |
| | 2972 | TypeTableEntry *underlying_meta_type = get_underlying_type(meta_type); |
| | 2973 | switch (underlying_meta_type->id) { |
| | 2974 | case TypeTableEntryIdTypeDecl: |
| | 2975 | zig_unreachable(); |
| | 2976 | case TypeTableEntryIdInvalid: |
| | 2977 | return ira->codegen->builtin_types.entry_invalid; |
| | 2978 | case TypeTableEntryIdVoid: |
| | 2979 | case TypeTableEntryIdBool: |
| | 2980 | case TypeTableEntryIdInt: |
| | 2981 | case TypeTableEntryIdFloat: |
| | 2982 | case TypeTableEntryIdPointer: |
| | 2983 | case TypeTableEntryIdArray: |
| | 2984 | case TypeTableEntryIdStruct: |
| | 2985 | case TypeTableEntryIdMaybe: |
| | 2986 | case TypeTableEntryIdErrorUnion: |
| | 2987 | case TypeTableEntryIdPureError: |
| | 2988 | case TypeTableEntryIdEnum: |
| | 2989 | case TypeTableEntryIdUnion: |
| | 2990 | case TypeTableEntryIdFn: |
| | 2991 | case TypeTableEntryIdGenericFn: |
| | 2992 | { |
| | 2993 | ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base, |
| | 2994 | value->static_value.depends_on_compile_var); |
| | 2995 | TypeTableEntry *result_type = get_error_type(ira->codegen, meta_type); |
| | 2996 | out_val->data.x_type = result_type; |
| | 2997 | return ira->codegen->builtin_types.entry_type; |
| | 2998 | } |
| | 2999 | case TypeTableEntryIdMetaType: |
| | 3000 | case TypeTableEntryIdNumLitFloat: |
| | 3001 | case TypeTableEntryIdNumLitInt: |
| | 3002 | case TypeTableEntryIdUndefLit: |
| | 3003 | case TypeTableEntryIdNullLit: |
| | 3004 | case TypeTableEntryIdNamespace: |
| | 3005 | case TypeTableEntryIdBlock: |
| | 3006 | case TypeTableEntryIdUnreachable: |
| | 3007 | case TypeTableEntryIdVar: |
| | 3008 | add_node_error(ira->codegen, un_op_instruction->base.source_node, |
| | 3009 | buf_sprintf("unable to wrap type '%s' in error type", buf_ptr(&meta_type->name))); |
| | 3010 | // TODO if meta_type is type decl, add note pointing to type decl declaration |
| | 3011 | return ira->codegen->builtin_types.entry_invalid; |
| | 3012 | } |
| | 3013 | zig_unreachable(); |
| | 3014 | } |
| | 3015 | |
| 2973 | static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { | 3016 | static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { |
| 2974 | IrUnOp op_id = un_op_instruction->op_id; | 3017 | IrUnOp op_id = un_op_instruction->op_id; |
| 2975 | switch (op_id) { | 3018 | switch (op_id) { |
| ... | @@ -2977,7 +3020,6 @@ static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructio | ... | @@ -2977,7 +3020,6 @@ static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructio |
| 2977 | zig_unreachable(); | 3020 | zig_unreachable(); |
| 2978 | case IrUnOpBoolNot: | 3021 | case IrUnOpBoolNot: |
| 2979 | return ir_analyze_unary_bool_not(ira, un_op_instruction); | 3022 | return ir_analyze_unary_bool_not(ira, un_op_instruction); |
| 2980 | zig_panic("TODO analyze PrefixOpBoolNot"); | | |
| 2981 | case IrUnOpBinNot: | 3023 | case IrUnOpBinNot: |
| 2982 | zig_panic("TODO analyze PrefixOpBinNot"); | 3024 | zig_panic("TODO analyze PrefixOpBinNot"); |
| 2983 | //{ | 3025 | //{ |
| ... | @@ -3106,31 +3148,7 @@ static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructio | ... | @@ -3106,31 +3148,7 @@ static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructio |
| 3106 | // } | 3148 | // } |
| 3107 | //} | 3149 | //} |
| 3108 | case IrUnOpError: | 3150 | case IrUnOpError: |
| 3109 | zig_panic("TODO analyze PrefixOpError"); | 3151 | return ir_analyze_unary_prefix_op_err(ira, un_op_instruction); |
| 3110 | //{ | | |
| 3111 | // TypeTableEntry *type_entry = analyze_expression(g, import, context, nullptr, *expr_node); | | |
| 3112 | | | |
| 3113 | // if (type_entry->id == TypeTableEntryIdInvalid) { | | |
| 3114 | // return type_entry; | | |
| 3115 | // } else if (type_entry->id == TypeTableEntryIdMetaType) { | | |
| 3116 | // TypeTableEntry *meta_type = resolve_type(g, *expr_node); | | |
| 3117 | // if (meta_type->id == TypeTableEntryIdInvalid) { | | |
| 3118 | // return meta_type; | | |
| 3119 | // } else if (meta_type->id == TypeTableEntryIdUnreachable) { | | |
| 3120 | // add_node_error(g, node, buf_create_from_str("unable to wrap unreachable in error type")); | | |
| 3121 | // return g->builtin_types.entry_invalid; | | |
| 3122 | // } else { | | |
| 3123 | // return resolve_expr_const_val_as_type(g, node, get_error_type(g, meta_type), false); | | |
| 3124 | // } | | |
| 3125 | // } else if (type_entry->id == TypeTableEntryIdUnreachable) { | | |
| 3126 | // add_node_error(g, *expr_node, buf_sprintf("unable to wrap unreachable in error type")); | | |
| 3127 | // return g->builtin_types.entry_invalid; | | |
| 3128 | // } else { | | |
| 3129 | // // TODO eval const expr | | |
| 3130 | // return get_error_type(g, type_entry); | | |
| 3131 | // } | | |
| 3132 | | | |
| 3133 | //} | | |
| 3134 | case IrUnOpUnwrapError: | 3152 | case IrUnOpUnwrapError: |
| 3135 | zig_panic("TODO analyze PrefixOpUnwrapError"); | 3153 | zig_panic("TODO analyze PrefixOpUnwrapError"); |
| 3136 | //{ | 3154 | //{ |
| ... | @@ -3691,6 +3709,59 @@ static TypeTableEntry *ir_analyze_instruction_set_fn_test(IrAnalyze *ira, | ... | @@ -3691,6 +3709,59 @@ static TypeTableEntry *ir_analyze_instruction_set_fn_test(IrAnalyze *ira, |
| 3691 | return ira->codegen->builtin_types.entry_void; | 3709 | return ira->codegen->builtin_types.entry_void; |
| 3692 | } | 3710 | } |
| 3693 | | 3711 | |
| | 3712 | static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| | 3713 | IrInstructionSliceType *slice_type_instruction) |
| | 3714 | { |
| | 3715 | IrInstruction *child_type = slice_type_instruction->child_type->other; |
| | 3716 | if (child_type->type_entry->id == TypeTableEntryIdInvalid) |
| | 3717 | return ira->codegen->builtin_types.entry_invalid; |
| | 3718 | bool is_const = slice_type_instruction->is_const; |
| | 3719 | |
| | 3720 | TypeTableEntry *resolved_child_type = ir_resolve_type(ira, child_type); |
| | 3721 | TypeTableEntry *canon_child_type = get_underlying_type(resolved_child_type); |
| | 3722 | switch (canon_child_type->id) { |
| | 3723 | case TypeTableEntryIdTypeDecl: |
| | 3724 | zig_unreachable(); |
| | 3725 | case TypeTableEntryIdInvalid: |
| | 3726 | return ira->codegen->builtin_types.entry_invalid; |
| | 3727 | case TypeTableEntryIdVar: |
| | 3728 | case TypeTableEntryIdUnreachable: |
| | 3729 | case TypeTableEntryIdUndefLit: |
| | 3730 | case TypeTableEntryIdNullLit: |
| | 3731 | case TypeTableEntryIdBlock: |
| | 3732 | add_node_error(ira->codegen, slice_type_instruction->base.source_node, |
| | 3733 | buf_sprintf("slice of type '%s' not allowed", buf_ptr(&resolved_child_type->name))); |
| | 3734 | // TODO if this is a typedecl, add error note showing the declaration of the type decl |
| | 3735 | return ira->codegen->builtin_types.entry_invalid; |
| | 3736 | case TypeTableEntryIdMetaType: |
| | 3737 | case TypeTableEntryIdVoid: |
| | 3738 | case TypeTableEntryIdBool: |
| | 3739 | case TypeTableEntryIdInt: |
| | 3740 | case TypeTableEntryIdFloat: |
| | 3741 | case TypeTableEntryIdPointer: |
| | 3742 | case TypeTableEntryIdArray: |
| | 3743 | case TypeTableEntryIdStruct: |
| | 3744 | case TypeTableEntryIdNumLitFloat: |
| | 3745 | case TypeTableEntryIdNumLitInt: |
| | 3746 | case TypeTableEntryIdMaybe: |
| | 3747 | case TypeTableEntryIdErrorUnion: |
| | 3748 | case TypeTableEntryIdPureError: |
| | 3749 | case TypeTableEntryIdEnum: |
| | 3750 | case TypeTableEntryIdUnion: |
| | 3751 | case TypeTableEntryIdFn: |
| | 3752 | case TypeTableEntryIdNamespace: |
| | 3753 | case TypeTableEntryIdGenericFn: |
| | 3754 | { |
| | 3755 | TypeTableEntry *result_type = get_slice_type(ira->codegen, resolved_child_type, is_const); |
| | 3756 | ConstExprValue *out_val = ir_build_const_from(ira, &slice_type_instruction->base, |
| | 3757 | child_type->static_value.depends_on_compile_var); |
| | 3758 | out_val->data.x_type = result_type; |
| | 3759 | return ira->codegen->builtin_types.entry_type; |
| | 3760 | } |
| | 3761 | } |
| | 3762 | zig_unreachable(); |
| | 3763 | } |
| | 3764 | |
| 3694 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { | 3765 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { |
| 3695 | switch (instruction->id) { | 3766 | switch (instruction->id) { |
| 3696 | case IrInstructionIdInvalid: | 3767 | case IrInstructionIdInvalid: |
| ... | @@ -3735,11 +3806,14 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -3735,11 +3806,14 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 3735 | return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction); | 3806 | return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction); |
| 3736 | case IrInstructionIdSetFnTest: | 3807 | case IrInstructionIdSetFnTest: |
| 3737 | return ir_analyze_instruction_set_fn_test(ira, (IrInstructionSetFnTest *)instruction); | 3808 | return ir_analyze_instruction_set_fn_test(ira, (IrInstructionSetFnTest *)instruction); |
| | 3809 | case IrInstructionIdSliceType: |
| | 3810 | return ir_analyze_instruction_slice_type(ira, (IrInstructionSliceType *)instruction); |
| 3738 | case IrInstructionIdSwitchBr: | 3811 | case IrInstructionIdSwitchBr: |
| 3739 | case IrInstructionIdCast: | 3812 | case IrInstructionIdCast: |
| 3740 | case IrInstructionIdContainerInitList: | 3813 | case IrInstructionIdContainerInitList: |
| 3741 | case IrInstructionIdContainerInitFields: | 3814 | case IrInstructionIdContainerInitFields: |
| 3742 | case IrInstructionIdStructFieldPtr: | 3815 | case IrInstructionIdStructFieldPtr: |
| | 3816 | case IrInstructionIdArrayType: |
| 3743 | zig_panic("TODO analyze more instructions"); | 3817 | zig_panic("TODO analyze more instructions"); |
| 3744 | } | 3818 | } |
| 3745 | zig_unreachable(); | 3819 | zig_unreachable(); |
| ... | @@ -3836,6 +3910,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -3836,6 +3910,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 3836 | case IrInstructionIdPtrTypeChild: | 3910 | case IrInstructionIdPtrTypeChild: |
| 3837 | case IrInstructionIdReadField: | 3911 | case IrInstructionIdReadField: |
| 3838 | case IrInstructionIdStructFieldPtr: | 3912 | case IrInstructionIdStructFieldPtr: |
| | 3913 | case IrInstructionIdArrayType: |
| | 3914 | case IrInstructionIdSliceType: |
| 3839 | return false; | 3915 | return false; |
| 3840 | } | 3916 | } |
| 3841 | zig_unreachable(); | 3917 | zig_unreachable(); |
| ... | @@ -6782,53 +6858,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { | ... | @@ -6782,53 +6858,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { |
| 6782 | // false, nullptr, false); | 6858 | // false, nullptr, false); |
| 6783 | //} | 6859 | //} |
| 6784 | // | 6860 | // |
| 6785 | //static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import, BlockContext *context, | | |
| 6786 | // TypeTableEntry *expected_type, AstNode *node) | | |
| 6787 | //{ | | |
| 6788 | // AstNode *size_node = node->data.array_type.size; | | |
| 6789 | // | | |
| 6790 | // TypeTableEntry *child_type = analyze_type_expr_pointer_only(g, import, context, | | |
| 6791 | // node->data.array_type.child_type, true); | | |
| 6792 | // | | |
| 6793 | // if (child_type->id == TypeTableEntryIdUnreachable) { | | |
| 6794 | // add_node_error(g, node, buf_create_from_str("array of unreachable not allowed")); | | |
| 6795 | // return g->builtin_types.entry_invalid; | | |
| 6796 | // } else if (child_type->id == TypeTableEntryIdInvalid) { | | |
| 6797 | // return g->builtin_types.entry_invalid; | | |
| 6798 | // } | | |
| 6799 | // | | |
| 6800 | // if (size_node) { | | |
| 6801 | // child_type = analyze_type_expr(g, import, context, node->data.array_type.child_type); | | |
| 6802 | // TypeTableEntry *size_type = analyze_expression(g, import, context, | | |
| 6803 | // g->builtin_types.entry_usize, size_node); | | |
| 6804 | // if (size_type->id == TypeTableEntryIdInvalid) { | | |
| 6805 | // return g->builtin_types.entry_invalid; | | |
| 6806 | // } | | |
| 6807 | // | | |
| 6808 | // ConstExprValue *const_val = &get_resolved_expr(size_node)->const_val; | | |
| 6809 | // if (const_val->ok) { | | |
| 6810 | // if (const_val->data.x_bignum.is_negative) { | | |
| 6811 | // add_node_error(g, size_node, | | |
| 6812 | // buf_sprintf("array size %s is negative", | | |
| 6813 | // buf_ptr(bignum_to_buf(&const_val->data.x_bignum)))); | | |
| 6814 | // return g->builtin_types.entry_invalid; | | |
| 6815 | // } else { | | |
| 6816 | // return resolve_expr_const_val_as_type(g, node, | | |
| 6817 | // get_array_type(g, child_type, const_val->data.x_bignum.data.x_uint), false); | | |
| 6818 | // } | | |
| 6819 | // } else if (context->fn_entry) { | | |
| 6820 | // return resolve_expr_const_val_as_type(g, node, | | |
| 6821 | // get_slice_type(g, child_type, node->data.array_type.is_const), false); | | |
| 6822 | // } else { | | |
| 6823 | // add_node_error(g, first_executing_node(size_node), | | |
| 6824 | // buf_sprintf("unable to evaluate constant expression")); | | |
| 6825 | // return g->builtin_types.entry_invalid; | | |
| 6826 | // } | | |
| 6827 | // } else { | | |
| 6828 | // TypeTableEntry *slice_type = get_slice_type(g, child_type, node->data.array_type.is_const); | | |
| 6829 | // return resolve_expr_const_val_as_type(g, node, slice_type, false); | | |
| 6830 | // } | | |
| 6831 | //} | | |
| 6832 | // | 6861 | // |
| 6833 | //static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 6862 | //static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 6834 | // TypeTableEntry *expected_type, AstNode *node) | 6863 | // TypeTableEntry *expected_type, AstNode *node) |
| ... | @@ -7218,3 +7247,126 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { | ... | @@ -7218,3 +7247,126 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { |
| 7218 | // } | 7247 | // } |
| 7219 | //} | 7248 | //} |
| 7220 | // | 7249 | // |
| | 7250 | //static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| | 7251 | // TypeTableEntry *expected_type, AstNode *node) |
| | 7252 | //{ |
| | 7253 | // AstNode *size_node = node->data.array_type.size; |
| | 7254 | // |
| | 7255 | // TypeTableEntry *child_type = analyze_type_expr_pointer_only(g, import, context, |
| | 7256 | // node->data.array_type.child_type, true); |
| | 7257 | // |
| | 7258 | // if (child_type->id == TypeTableEntryIdUnreachable) { |
| | 7259 | // add_node_error(g, node, buf_create_from_str("array of unreachable not allowed")); |
| | 7260 | // return g->builtin_types.entry_invalid; |
| | 7261 | // } else if (child_type->id == TypeTableEntryIdInvalid) { |
| | 7262 | // return g->builtin_types.entry_invalid; |
| | 7263 | // } |
| | 7264 | // |
| | 7265 | // if (size_node) { |
| | 7266 | // child_type = analyze_type_expr(g, import, context, node->data.array_type.child_type); |
| | 7267 | // TypeTableEntry *size_type = analyze_expression(g, import, context, |
| | 7268 | // g->builtin_types.entry_usize, size_node); |
| | 7269 | // if (size_type->id == TypeTableEntryIdInvalid) { |
| | 7270 | // return g->builtin_types.entry_invalid; |
| | 7271 | // } |
| | 7272 | // |
| | 7273 | // ConstExprValue *const_val = &get_resolved_expr(size_node)->const_val; |
| | 7274 | // if (const_val->ok) { |
| | 7275 | // if (const_val->data.x_bignum.is_negative) { |
| | 7276 | // add_node_error(g, size_node, |
| | 7277 | // buf_sprintf("array size %s is negative", |
| | 7278 | // buf_ptr(bignum_to_buf(&const_val->data.x_bignum)))); |
| | 7279 | // return g->builtin_types.entry_invalid; |
| | 7280 | // } else { |
| | 7281 | // return resolve_expr_const_val_as_type(g, node, |
| | 7282 | // get_array_type(g, child_type, const_val->data.x_bignum.data.x_uint), false); |
| | 7283 | // } |
| | 7284 | // } else if (context->fn_entry) { |
| | 7285 | // return resolve_expr_const_val_as_type(g, node, |
| | 7286 | // get_slice_type(g, child_type, node->data.array_type.is_const), false); |
| | 7287 | // } else { |
| | 7288 | // add_node_error(g, first_executing_node(size_node), |
| | 7289 | // buf_sprintf("unable to evaluate constant expression")); |
| | 7290 | // return g->builtin_types.entry_invalid; |
| | 7291 | // } |
| | 7292 | // } else { |
| | 7293 | // TypeTableEntry *slice_type = get_slice_type(g, child_type, node->data.array_type.is_const); |
| | 7294 | // return resolve_expr_const_val_as_type(g, node, slice_type, false); |
| | 7295 | // } |
| | 7296 | //} |
| | 7297 | //static size_t get_conditional_defer_count(BlockContext *inner_block, BlockContext *outer_block) { |
| | 7298 | // size_t result = 0; |
| | 7299 | // while (inner_block != outer_block) { |
| | 7300 | // if (inner_block->node->type == NodeTypeDefer && |
| | 7301 | // (inner_block->node->data.defer.kind == ReturnKindError || |
| | 7302 | // inner_block->node->data.defer.kind == ReturnKindMaybe)) |
| | 7303 | // { |
| | 7304 | // result += 1; |
| | 7305 | // } |
| | 7306 | // inner_block = inner_block->parent; |
| | 7307 | // } |
| | 7308 | // return result; |
| | 7309 | //} |
| | 7310 | |
| | 7311 | |
| | 7312 | //static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *source_node, IrInstruction *value, ReturnKnowledge rk) { |
| | 7313 | // BlockContext *defer_inner_block = source_node->block_context; |
| | 7314 | // BlockContext *defer_outer_block = irb->node->block_context; |
| | 7315 | // if (rk == ReturnKnowledgeUnknown) { |
| | 7316 | // if (get_conditional_defer_count(defer_inner_block, defer_outer_block) > 0) { |
| | 7317 | // // generate branching code that checks the return value and generates defers |
| | 7318 | // // if the return value is error |
| | 7319 | // zig_panic("TODO"); |
| | 7320 | // } |
| | 7321 | // } else if (rk != ReturnKnowledgeSkipDefers) { |
| | 7322 | // ir_gen_defers_for_block(irb, defer_inner_block, defer_outer_block, |
| | 7323 | // rk == ReturnKnowledgeKnownError, rk == ReturnKnowledgeKnownNull); |
| | 7324 | // } |
| | 7325 | // |
| | 7326 | // return ir_build_return(irb, source_node, value); |
| | 7327 | //} |
| | 7328 | /* |
| | 7329 | static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *node) { |
| | 7330 | assert(node->type == NodeTypeGoto); |
| | 7331 | Buf *label_name = node->data.goto_expr.name; |
| | 7332 | BlockContext *context = node->block_context; |
| | 7333 | assert(context); |
| | 7334 | LabelTableEntry *label = find_label(g, context, label_name); |
| | 7335 | |
| | 7336 | if (!label) { |
| | 7337 | add_node_error(g, node, buf_sprintf("no label in scope named '%s'", buf_ptr(label_name))); |
| | 7338 | return; |
| | 7339 | } |
| | 7340 | |
| | 7341 | label->used = true; |
| | 7342 | node->data.goto_expr.label_entry = label; |
| | 7343 | } |
| | 7344 | |
| | 7345 | for (size_t i = 0; i < fn_table_entry->goto_list.length; i += 1) { |
| | 7346 | AstNode *goto_node = fn_table_entry->goto_list.at(i); |
| | 7347 | assert(goto_node->type == NodeTypeGoto); |
| | 7348 | analyze_goto_pass2(g, import, goto_node); |
| | 7349 | } |
| | 7350 | |
| | 7351 | for (size_t i = 0; i < fn_table_entry->all_labels.length; i += 1) { |
| | 7352 | LabelTableEntry *label = fn_table_entry->all_labels.at(i); |
| | 7353 | if (!label->used) { |
| | 7354 | add_node_error(g, label->decl_node, |
| | 7355 | buf_sprintf("label '%s' defined but not used", |
| | 7356 | buf_ptr(label->decl_node->data.label.name))); |
| | 7357 | } |
| | 7358 | } |
| | 7359 | */ |
| | 7360 | |
| | 7361 | //static LabelTableEntry *find_label(CodeGen *g, BlockContext *orig_context, Buf *name) { |
| | 7362 | // BlockContext *context = orig_context; |
| | 7363 | // while (context && context->fn_entry) { |
| | 7364 | // auto entry = context->label_table.maybe_get(name); |
| | 7365 | // if (entry) { |
| | 7366 | // return entry->value; |
| | 7367 | // } |
| | 7368 | // context = context->parent; |
| | 7369 | // } |
| | 7370 | // return nullptr; |
| | 7371 | //} |
| | 7372 | |