| ... | @@ -40,6 +40,12 @@ static size_t exec_next_debug_id(IrExecutable *exec) { | ... | @@ -40,6 +40,12 @@ static size_t exec_next_debug_id(IrExecutable *exec) { |
| 40 | return result; | 40 | return result; |
| 41 | } | 41 | } |
| 42 | | 42 | |
| | 43 | static size_t exec_next_var_slot(IrExecutable *exec) { |
| | 44 | size_t result = exec->var_slot_count; |
| | 45 | exec->var_slot_count += 1; |
| | 46 | return result; |
| | 47 | } |
| | 48 | |
| 43 | static void ir_link_new_instruction(IrInstruction *new_instruction, IrInstruction *old_instruction) { | 49 | static void ir_link_new_instruction(IrInstruction *new_instruction, IrInstruction *old_instruction) { |
| 44 | new_instruction->other = old_instruction; | 50 | new_instruction->other = old_instruction; |
| 45 | old_instruction->other = new_instruction; | 51 | old_instruction->other = new_instruction; |
| ... | @@ -63,6 +69,10 @@ static void ir_ref_instruction(IrInstruction *instruction) { | ... | @@ -63,6 +69,10 @@ static void ir_ref_instruction(IrInstruction *instruction) { |
| 63 | instruction->ref_count += 1; | 69 | instruction->ref_count += 1; |
| 64 | } | 70 | } |
| 65 | | 71 | |
| | 72 | static void ir_ref_var(VariableTableEntry *var) { |
| | 73 | var->ref_count += 1; |
| | 74 | } |
| | 75 | |
| 66 | static IrBasicBlock *ir_build_basic_block(IrBuilder *irb, const char *name_hint) { | 76 | static IrBasicBlock *ir_build_basic_block(IrBuilder *irb, const char *name_hint) { |
| 67 | IrBasicBlock *result = allocate<IrBasicBlock>(1); | 77 | IrBasicBlock *result = allocate<IrBasicBlock>(1); |
| 68 | result->name_hint = name_hint; | 78 | result->name_hint = name_hint; |
| ... | @@ -101,6 +111,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionBinOp *) { | ... | @@ -101,6 +111,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionBinOp *) { |
| 101 | return IrInstructionIdBinOp; | 111 | return IrInstructionIdBinOp; |
| 102 | } | 112 | } |
| 103 | | 113 | |
| | 114 | static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclVar *) { |
| | 115 | return IrInstructionIdDeclVar; |
| | 116 | } |
| | 117 | |
| 104 | static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadVar *) { | 118 | static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadVar *) { |
| 105 | return IrInstructionIdLoadVar; | 119 | return IrInstructionIdLoadVar; |
| 106 | } | 120 | } |
| ... | @@ -295,6 +309,9 @@ static IrInstruction *ir_build_load_var(IrBuilder *irb, AstNode *source_node, Va | ... | @@ -295,6 +309,9 @@ static IrInstruction *ir_build_load_var(IrBuilder *irb, AstNode *source_node, Va |
| 295 | IrInstructionLoadVar *load_var_instruction = ir_build_instruction<IrInstructionLoadVar>(irb, source_node); | 309 | IrInstructionLoadVar *load_var_instruction = ir_build_instruction<IrInstructionLoadVar>(irb, source_node); |
| 296 | load_var_instruction->base.type_entry = var->type; | 310 | load_var_instruction->base.type_entry = var->type; |
| 297 | load_var_instruction->var = var; | 311 | load_var_instruction->var = var; |
| | 312 | |
| | 313 | ir_ref_var(var); |
| | 314 | |
| 298 | return &load_var_instruction->base; | 315 | return &load_var_instruction->base; |
| 299 | } | 316 | } |
| 300 | | 317 | |
| ... | @@ -443,6 +460,36 @@ static IrInstruction *ir_build_unreachable_from(IrBuilder *irb, IrInstruction *o | ... | @@ -443,6 +460,36 @@ static IrInstruction *ir_build_unreachable_from(IrBuilder *irb, IrInstruction *o |
| 443 | return new_instruction; | 460 | return new_instruction; |
| 444 | } | 461 | } |
| 445 | | 462 | |
| | 463 | //static IrInstruction *ir_build_store(IrBuilder *irb, AstNode *source_node, |
| | 464 | // VariableTableEntry *var, IrInstruction *value) |
| | 465 | //{ |
| | 466 | // IrInstructionStoreVar *store_instruction = ir_build_instruction<IrInstructionStoreVar>(irb, source_node); |
| | 467 | // store_instruction->base.static_value.ok = true; |
| | 468 | // store_instruction->base.type_entry = irb->codegen->builtin_types.entry_void; |
| | 469 | // store_instruction->var = var; |
| | 470 | // store_instruction->value = value; |
| | 471 | // return &store_instruction->base; |
| | 472 | //} |
| | 473 | |
| | 474 | static IrInstruction *ir_build_var_decl(IrBuilder *irb, AstNode *source_node, |
| | 475 | VariableTableEntry *var, IrInstruction *var_type, IrInstruction *init_value) |
| | 476 | { |
| | 477 | IrInstructionDeclVar *decl_var_instruction = ir_build_instruction<IrInstructionDeclVar>(irb, source_node); |
| | 478 | decl_var_instruction->base.static_value.ok = true; |
| | 479 | decl_var_instruction->base.type_entry = irb->codegen->builtin_types.entry_void; |
| | 480 | decl_var_instruction->var = var; |
| | 481 | decl_var_instruction->var_type = var_type; |
| | 482 | decl_var_instruction->init_value = init_value; |
| | 483 | return &decl_var_instruction->base; |
| | 484 | } |
| | 485 | |
| | 486 | static IrInstruction *ir_build_var_decl_from(IrBuilder *irb, IrInstruction *old_instruction, |
| | 487 | VariableTableEntry *var, IrInstruction *var_type, IrInstruction *init_value) |
| | 488 | { |
| | 489 | IrInstruction *new_instruction = ir_build_var_decl(irb, old_instruction->source_node, var, var_type, init_value); |
| | 490 | ir_link_new_instruction(new_instruction, old_instruction); |
| | 491 | return new_instruction; |
| | 492 | } |
| 446 | | 493 | |
| 447 | //static size_t get_conditional_defer_count(BlockContext *inner_block, BlockContext *outer_block) { | 494 | //static size_t get_conditional_defer_count(BlockContext *inner_block, BlockContext *outer_block) { |
| 448 | // size_t result = 0; | 495 | // size_t result = 0; |
| ... | @@ -497,6 +544,58 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { | ... | @@ -497,6 +544,58 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { |
| 497 | irb->current_basic_block = basic_block; | 544 | irb->current_basic_block = basic_block; |
| 498 | } | 545 | } |
| 499 | | 546 | |
| | 547 | // Set name to nullptr to make the variable anonymous (not visible to programmer). |
| | 548 | static VariableTableEntry *ir_add_local_var(IrBuilder *irb, AstNode *node, Buf *name, |
| | 549 | bool is_const, bool is_shadowable) |
| | 550 | { |
| | 551 | VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1); |
| | 552 | variable_entry->block_context = node->block_context; |
| | 553 | variable_entry->import = node->owner; |
| | 554 | variable_entry->shadowable = is_shadowable; |
| | 555 | variable_entry->slot_index = exec_next_var_slot(irb->exec); |
| | 556 | |
| | 557 | if (name) { |
| | 558 | buf_init_from_buf(&variable_entry->name, name); |
| | 559 | |
| | 560 | VariableTableEntry *existing_var = find_variable(irb->codegen, node->block_context, name); |
| | 561 | if (existing_var && !existing_var->shadowable) { |
| | 562 | ErrorMsg *msg = add_node_error(irb->codegen, node, |
| | 563 | buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); |
| | 564 | add_error_note(irb->codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here")); |
| | 565 | variable_entry->type = irb->codegen->builtin_types.entry_invalid; |
| | 566 | } else { |
| | 567 | auto primitive_table_entry = irb->codegen->primitive_type_table.maybe_get(name); |
| | 568 | if (primitive_table_entry) { |
| | 569 | TypeTableEntry *type = primitive_table_entry->value; |
| | 570 | add_node_error(irb->codegen, node, |
| | 571 | buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name))); |
| | 572 | variable_entry->type = irb->codegen->builtin_types.entry_invalid; |
| | 573 | } else { |
| | 574 | AstNode *decl_node = find_decl(node->block_context, name); |
| | 575 | if (decl_node && decl_node->type != NodeTypeVariableDeclaration) { |
| | 576 | ErrorMsg *msg = add_node_error(irb->codegen, node, |
| | 577 | buf_sprintf("redefinition of '%s'", buf_ptr(name))); |
| | 578 | add_error_note(irb->codegen, msg, decl_node, buf_sprintf("previous definition is here")); |
| | 579 | variable_entry->type = irb->codegen->builtin_types.entry_invalid; |
| | 580 | } |
| | 581 | } |
| | 582 | } |
| | 583 | |
| | 584 | node->block_context->var_table.put(&variable_entry->name, variable_entry); |
| | 585 | } else { |
| | 586 | // TODO replace _anon with @anon and make sure all tests still pass |
| | 587 | buf_init_from_str(&variable_entry->name, "_anon"); |
| | 588 | } |
| | 589 | if (node->block_context->fn_entry) { |
| | 590 | node->block_context->fn_entry->variable_list.append(variable_entry); |
| | 591 | } |
| | 592 | |
| | 593 | variable_entry->is_const = is_const; |
| | 594 | variable_entry->decl_node = node; |
| | 595 | |
| | 596 | return variable_entry; |
| | 597 | } |
| | 598 | |
| 500 | static IrInstruction *ir_gen_block(IrBuilder *irb, AstNode *block_node) { | 599 | static IrInstruction *ir_gen_block(IrBuilder *irb, AstNode *block_node) { |
| 501 | assert(block_node->type == NodeTypeBlock); | 600 | assert(block_node->type == NodeTypeBlock); |
| 502 | | 601 | |
| ... | @@ -883,6 +982,38 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node) | ... | @@ -883,6 +982,38 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node) |
| 883 | } | 982 | } |
| 884 | } | 983 | } |
| 885 | | 984 | |
| | 985 | static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) { |
| | 986 | assert(node->type == NodeTypeVariableDeclaration); |
| | 987 | |
| | 988 | AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration; |
| | 989 | |
| | 990 | IrInstruction *type_instruction; |
| | 991 | if (variable_declaration->type != nullptr) { |
| | 992 | type_instruction = ir_gen_node(irb, variable_declaration->type, node->block_context); |
| | 993 | if (type_instruction == irb->codegen->invalid_instruction) |
| | 994 | return type_instruction; |
| | 995 | } else { |
| | 996 | type_instruction = nullptr; |
| | 997 | } |
| | 998 | |
| | 999 | IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, node->block_context); |
| | 1000 | if (init_value == irb->codegen->invalid_instruction) |
| | 1001 | return init_value; |
| | 1002 | |
| | 1003 | bool is_shadowable = false; |
| | 1004 | bool is_const = variable_declaration->is_const; |
| | 1005 | bool is_extern = variable_declaration->is_extern; |
| | 1006 | VariableTableEntry *var = ir_add_local_var(irb, node, variable_declaration->symbol, is_const, is_shadowable); |
| | 1007 | |
| | 1008 | if (!is_extern && !variable_declaration->expr) { |
| | 1009 | var->type = irb->codegen->builtin_types.entry_invalid; |
| | 1010 | add_node_error(irb->codegen, node, buf_sprintf("variables must be initialized")); |
| | 1011 | return irb->codegen->invalid_instruction; |
| | 1012 | } |
| | 1013 | |
| | 1014 | return ir_build_var_decl(irb, node, var, type_instruction, init_value); |
| | 1015 | } |
| | 1016 | |
| 886 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockContext *block_context, | 1017 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockContext *block_context, |
| 887 | bool pointer_only) | 1018 | bool pointer_only) |
| 888 | { | 1019 | { |
| ... | @@ -906,10 +1037,11 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont | ... | @@ -906,10 +1037,11 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont |
| 906 | return ir_gen_prefix_op_expr(irb, node); | 1037 | return ir_gen_prefix_op_expr(irb, node); |
| 907 | case NodeTypeContainerInitExpr: | 1038 | case NodeTypeContainerInitExpr: |
| 908 | return ir_gen_container_init_expr(irb, node); | 1039 | return ir_gen_container_init_expr(irb, node); |
| | 1040 | case NodeTypeVariableDeclaration: |
| | 1041 | return ir_gen_var_decl(irb, node); |
| 909 | case NodeTypeUnwrapErrorExpr: | 1042 | case NodeTypeUnwrapErrorExpr: |
| 910 | case NodeTypeReturnExpr: | 1043 | case NodeTypeReturnExpr: |
| 911 | case NodeTypeDefer: | 1044 | case NodeTypeDefer: |
| 912 | case NodeTypeVariableDeclaration: | | |
| 913 | case NodeTypeArrayAccessExpr: | 1045 | case NodeTypeArrayAccessExpr: |
| 914 | case NodeTypeSliceExpr: | 1046 | case NodeTypeSliceExpr: |
| 915 | case NodeTypeFieldAccessExpr: | 1047 | case NodeTypeFieldAccessExpr: |
| ... | @@ -1553,6 +1685,26 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -1553,6 +1685,26 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 1553 | return ira->codegen->invalid_instruction; | 1685 | return ira->codegen->invalid_instruction; |
| 1554 | } | 1686 | } |
| 1555 | | 1687 | |
| | 1688 | static TypeTableEntry *ir_get_canonical_type(IrAnalyze *ira, IrInstruction *type_value) { |
| | 1689 | if (type_value == ira->codegen->invalid_instruction) |
| | 1690 | return ira->codegen->builtin_types.entry_invalid; |
| | 1691 | |
| | 1692 | if (type_value->type_entry->id == TypeTableEntryIdInvalid) |
| | 1693 | return ira->codegen->builtin_types.entry_invalid; |
| | 1694 | |
| | 1695 | if (type_value->type_entry->id != TypeTableEntryIdMetaType) { |
| | 1696 | add_node_error(ira->codegen, type_value->source_node, buf_sprintf("expected type, found expression")); |
| | 1697 | return ira->codegen->builtin_types.entry_invalid; |
| | 1698 | } |
| | 1699 | |
| | 1700 | if (!type_value->static_value.ok) { |
| | 1701 | add_node_error(ira->codegen, type_value->source_node, buf_sprintf("unable to evaluate constant expression")); |
| | 1702 | return ira->codegen->builtin_types.entry_invalid; |
| | 1703 | } |
| | 1704 | |
| | 1705 | return get_underlying_type(type_value->static_value.data.x_type); |
| | 1706 | } |
| | 1707 | |
| 1556 | static IrInstruction *ir_get_casted_value(IrAnalyze *ira, IrInstruction *value, TypeTableEntry *expected_type) { | 1708 | static IrInstruction *ir_get_casted_value(IrAnalyze *ira, IrInstruction *value, TypeTableEntry *expected_type) { |
| 1557 | assert(value); | 1709 | assert(value); |
| 1558 | assert(value != ira->codegen->invalid_instruction); | 1710 | assert(value != ira->codegen->invalid_instruction); |
| ... | @@ -1915,6 +2067,119 @@ static TypeTableEntry *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructi | ... | @@ -1915,6 +2067,119 @@ static TypeTableEntry *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructi |
| 1915 | zig_unreachable(); | 2067 | zig_unreachable(); |
| 1916 | } | 2068 | } |
| 1917 | | 2069 | |
| | 2070 | static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstructionDeclVar *decl_var_instruction) { |
| | 2071 | VariableTableEntry *var = decl_var_instruction->var; |
| | 2072 | AstNodeVariableDeclaration *variable_declaration = &var->decl_node->data.variable_declaration; |
| | 2073 | bool is_export = (variable_declaration->top_level_decl.visib_mod == VisibModExport); |
| | 2074 | bool is_extern = variable_declaration->is_extern; |
| | 2075 | |
| | 2076 | var->ref_count = 0; |
| | 2077 | |
| | 2078 | TypeTableEntry *explicit_type = nullptr; |
| | 2079 | IrInstruction *var_type = nullptr; |
| | 2080 | if (decl_var_instruction->var_type != nullptr) { |
| | 2081 | var_type = decl_var_instruction->var_type->other; |
| | 2082 | explicit_type = ir_get_canonical_type(ira, var_type); |
| | 2083 | switch (explicit_type->id) { |
| | 2084 | case TypeTableEntryIdTypeDecl: |
| | 2085 | zig_unreachable(); |
| | 2086 | case TypeTableEntryIdInvalid: |
| | 2087 | explicit_type = ira->codegen->builtin_types.entry_invalid; |
| | 2088 | break; |
| | 2089 | case TypeTableEntryIdUnreachable: |
| | 2090 | case TypeTableEntryIdVar: |
| | 2091 | case TypeTableEntryIdNumLitFloat: |
| | 2092 | case TypeTableEntryIdNumLitInt: |
| | 2093 | case TypeTableEntryIdUndefLit: |
| | 2094 | case TypeTableEntryIdNullLit: |
| | 2095 | case TypeTableEntryIdBlock: |
| | 2096 | add_node_error(ira->codegen, var_type->source_node, |
| | 2097 | buf_sprintf("variable of type '%s' not allowed", buf_ptr(&explicit_type->name))); |
| | 2098 | explicit_type = ira->codegen->builtin_types.entry_invalid; |
| | 2099 | break; |
| | 2100 | case TypeTableEntryIdNamespace: |
| | 2101 | case TypeTableEntryIdMetaType: |
| | 2102 | case TypeTableEntryIdVoid: |
| | 2103 | case TypeTableEntryIdBool: |
| | 2104 | case TypeTableEntryIdInt: |
| | 2105 | case TypeTableEntryIdFloat: |
| | 2106 | case TypeTableEntryIdPointer: |
| | 2107 | case TypeTableEntryIdArray: |
| | 2108 | case TypeTableEntryIdStruct: |
| | 2109 | case TypeTableEntryIdMaybe: |
| | 2110 | case TypeTableEntryIdErrorUnion: |
| | 2111 | case TypeTableEntryIdPureError: |
| | 2112 | case TypeTableEntryIdEnum: |
| | 2113 | case TypeTableEntryIdUnion: |
| | 2114 | case TypeTableEntryIdFn: |
| | 2115 | case TypeTableEntryIdGenericFn: |
| | 2116 | // OK |
| | 2117 | break; |
| | 2118 | } |
| | 2119 | } |
| | 2120 | |
| | 2121 | IrInstruction *init_value = decl_var_instruction->init_value->other; |
| | 2122 | IrInstruction *casted_init_value = ir_get_casted_value(ira, init_value, explicit_type); |
| | 2123 | TypeTableEntry *result_type = get_underlying_type(casted_init_value->type_entry); |
| | 2124 | switch (result_type->id) { |
| | 2125 | case TypeTableEntryIdTypeDecl: |
| | 2126 | zig_unreachable(); |
| | 2127 | case TypeTableEntryIdInvalid: |
| | 2128 | result_type = ira->codegen->builtin_types.entry_invalid; |
| | 2129 | break; |
| | 2130 | case TypeTableEntryIdNumLitFloat: |
| | 2131 | case TypeTableEntryIdNumLitInt: |
| | 2132 | if (is_export || is_extern || !casted_init_value->static_value.ok) { |
| | 2133 | add_node_error(ira->codegen, var_type->source_node, buf_sprintf("unable to infer variable type")); |
| | 2134 | result_type = ira->codegen->builtin_types.entry_invalid; |
| | 2135 | } |
| | 2136 | break; |
| | 2137 | case TypeTableEntryIdUnreachable: |
| | 2138 | case TypeTableEntryIdVar: |
| | 2139 | case TypeTableEntryIdBlock: |
| | 2140 | add_node_error(ira->codegen, var_type->source_node, |
| | 2141 | buf_sprintf("variable of type '%s' not allowed", buf_ptr(&result_type->name))); |
| | 2142 | result_type = ira->codegen->builtin_types.entry_invalid; |
| | 2143 | break; |
| | 2144 | case TypeTableEntryIdMetaType: |
| | 2145 | case TypeTableEntryIdNamespace: |
| | 2146 | if (!casted_init_value->static_value.ok) { |
| | 2147 | add_node_error(ira->codegen, var_type->source_node, |
| | 2148 | buf_sprintf("variable of type '%s' must be constant", buf_ptr(&result_type->name))); |
| | 2149 | result_type = ira->codegen->builtin_types.entry_invalid; |
| | 2150 | } |
| | 2151 | break; |
| | 2152 | case TypeTableEntryIdUndefLit: |
| | 2153 | case TypeTableEntryIdNullLit: |
| | 2154 | case TypeTableEntryIdVoid: |
| | 2155 | case TypeTableEntryIdBool: |
| | 2156 | case TypeTableEntryIdInt: |
| | 2157 | case TypeTableEntryIdFloat: |
| | 2158 | case TypeTableEntryIdPointer: |
| | 2159 | case TypeTableEntryIdArray: |
| | 2160 | case TypeTableEntryIdStruct: |
| | 2161 | case TypeTableEntryIdMaybe: |
| | 2162 | case TypeTableEntryIdErrorUnion: |
| | 2163 | case TypeTableEntryIdPureError: |
| | 2164 | case TypeTableEntryIdEnum: |
| | 2165 | case TypeTableEntryIdUnion: |
| | 2166 | case TypeTableEntryIdFn: |
| | 2167 | case TypeTableEntryIdGenericFn: |
| | 2168 | // OK |
| | 2169 | break; |
| | 2170 | } |
| | 2171 | |
| | 2172 | var->type = result_type; |
| | 2173 | assert(var->type != nullptr); // should have been caught by the parser |
| | 2174 | |
| | 2175 | if (casted_init_value->static_value.ok) { |
| | 2176 | // TODO set the variable in the IrVarSlot |
| | 2177 | } |
| | 2178 | ir_build_var_decl_from(&ira->new_irb, &decl_var_instruction->base, var, var_type, casted_init_value); |
| | 2179 | |
| | 2180 | return ira->codegen->builtin_types.entry_void; |
| | 2181 | } |
| | 2182 | |
| 1918 | static TypeTableEntry *ir_analyze_instruction_load_var(IrAnalyze *ira, IrInstructionLoadVar *load_var_instruction) { | 2183 | static TypeTableEntry *ir_analyze_instruction_load_var(IrAnalyze *ira, IrInstructionLoadVar *load_var_instruction) { |
| 1919 | ir_build_load_var_from(&ira->new_irb, &load_var_instruction->base, load_var_instruction->var); | 2184 | ir_build_load_var_from(&ira->new_irb, &load_var_instruction->base, load_var_instruction->var); |
| 1920 | return load_var_instruction->var->type; | 2185 | return load_var_instruction->var->type; |
| ... | @@ -3473,6 +3738,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -3473,6 +3738,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 3473 | return ir_analyze_instruction_un_op(ira, (IrInstructionUnOp *)instruction); | 3738 | return ir_analyze_instruction_un_op(ira, (IrInstructionUnOp *)instruction); |
| 3474 | case IrInstructionIdBinOp: | 3739 | case IrInstructionIdBinOp: |
| 3475 | return ir_analyze_instruction_bin_op(ira, (IrInstructionBinOp *)instruction); | 3740 | return ir_analyze_instruction_bin_op(ira, (IrInstructionBinOp *)instruction); |
| | 3741 | case IrInstructionIdDeclVar: |
| | 3742 | return ir_analyze_instruction_decl_var(ira, (IrInstructionDeclVar *)instruction); |
| 3476 | case IrInstructionIdLoadVar: | 3743 | case IrInstructionIdLoadVar: |
| 3477 | return ir_analyze_instruction_load_var(ira, (IrInstructionLoadVar *)instruction); | 3744 | return ir_analyze_instruction_load_var(ira, (IrInstructionLoadVar *)instruction); |
| 3478 | case IrInstructionIdCall: | 3745 | case IrInstructionIdCall: |
| ... | @@ -3612,6 +3879,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -3612,6 +3879,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 3612 | case IrInstructionIdBr: | 3879 | case IrInstructionIdBr: |
| 3613 | case IrInstructionIdCondBr: | 3880 | case IrInstructionIdCondBr: |
| 3614 | case IrInstructionIdSwitchBr: | 3881 | case IrInstructionIdSwitchBr: |
| | 3882 | case IrInstructionIdDeclVar: |
| 3615 | case IrInstructionIdStoreVar: | 3883 | case IrInstructionIdStoreVar: |
| 3616 | case IrInstructionIdCall: | 3884 | case IrInstructionIdCall: |
| 3617 | case IrInstructionIdReturn: | 3885 | case IrInstructionIdReturn: |