| ... | @@ -3,6 +3,7 @@ | ... | @@ -3,6 +3,7 @@ |
| 3 | #include "eval.hpp" | 3 | #include "eval.hpp" |
| 4 | #include "ir.hpp" | 4 | #include "ir.hpp" |
| 5 | #include "ir_print.hpp" | 5 | #include "ir_print.hpp" |
| | 6 | #include "os.hpp" |
| 6 | | 7 | |
| 7 | struct IrExecContext { | 8 | struct IrExecContext { |
| 8 | ConstExprValue *mem_slot_list; | 9 | ConstExprValue *mem_slot_list; |
| ... | @@ -159,10 +160,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionStructFieldPtr * | ... | @@ -159,10 +160,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionStructFieldPtr * |
| 159 | return IrInstructionIdStructFieldPtr; | 160 | return IrInstructionIdStructFieldPtr; |
| 160 | } | 161 | } |
| 161 | | 162 | |
| 162 | static constexpr IrInstructionId ir_instruction_id(IrInstructionReadField *) { | | |
| 163 | return IrInstructionIdReadField; | | |
| 164 | } | | |
| 165 | | | |
| 166 | static constexpr IrInstructionId ir_instruction_id(IrInstructionElemPtr *) { | 163 | static constexpr IrInstructionId ir_instruction_id(IrInstructionElemPtr *) { |
| 167 | return IrInstructionIdElemPtr; | 164 | return IrInstructionIdElemPtr; |
| 168 | } | 165 | } |
| ... | @@ -267,6 +264,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionStaticEval *) { | ... | @@ -267,6 +264,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionStaticEval *) { |
| 267 | return IrInstructionIdStaticEval; | 264 | return IrInstructionIdStaticEval; |
| 268 | } | 265 | } |
| 269 | | 266 | |
| | 267 | static constexpr IrInstructionId ir_instruction_id(IrInstructionImport *) { |
| | 268 | return IrInstructionIdImport; |
| | 269 | } |
| | 270 | |
| | 271 | static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayLen *) { |
| | 272 | return IrInstructionIdArrayLen; |
| | 273 | } |
| | 274 | |
| 270 | template<typename T> | 275 | template<typename T> |
| 271 | static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) { | 276 | static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) { |
| 272 | T *special_instruction = allocate<T>(1); | 277 | T *special_instruction = allocate<T>(1); |
| ... | @@ -565,18 +570,6 @@ static IrInstruction *ir_build_field_ptr(IrBuilder *irb, AstNode *source_node, | ... | @@ -565,18 +570,6 @@ static IrInstruction *ir_build_field_ptr(IrBuilder *irb, AstNode *source_node, |
| 565 | return &instruction->base; | 570 | return &instruction->base; |
| 566 | } | 571 | } |
| 567 | | 572 | |
| 568 | static IrInstruction *ir_build_read_field(IrBuilder *irb, AstNode *source_node, | | |
| 569 | IrInstruction *container_ptr, Buf *field_name) | | |
| 570 | { | | |
| 571 | IrInstructionReadField *instruction = ir_build_instruction<IrInstructionReadField>(irb, source_node); | | |
| 572 | instruction->container_ptr = container_ptr; | | |
| 573 | instruction->field_name = field_name; | | |
| 574 | | | |
| 575 | ir_ref_instruction(container_ptr); | | |
| 576 | | | |
| 577 | return &instruction->base; | | |
| 578 | } | | |
| 579 | | | |
| 580 | static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, AstNode *source_node, | 573 | static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, AstNode *source_node, |
| 581 | IrInstruction *struct_ptr, TypeStructField *field) | 574 | IrInstruction *struct_ptr, TypeStructField *field) |
| 582 | { | 575 | { |
| ... | @@ -1087,6 +1080,32 @@ static IrInstruction *ir_build_static_eval(IrBuilder *irb, AstNode *source_node, | ... | @@ -1087,6 +1080,32 @@ static IrInstruction *ir_build_static_eval(IrBuilder *irb, AstNode *source_node, |
| 1087 | return &instruction->base; | 1080 | return &instruction->base; |
| 1088 | } | 1081 | } |
| 1089 | | 1082 | |
| | 1083 | static IrInstruction *ir_build_import(IrBuilder *irb, AstNode *source_node, IrInstruction *name) { |
| | 1084 | IrInstructionImport *instruction = ir_build_instruction<IrInstructionImport>(irb, source_node); |
| | 1085 | instruction->name = name; |
| | 1086 | |
| | 1087 | ir_ref_instruction(name); |
| | 1088 | |
| | 1089 | return &instruction->base; |
| | 1090 | } |
| | 1091 | |
| | 1092 | static IrInstruction *ir_build_array_len(IrBuilder *irb, AstNode *source_node, IrInstruction *array_value) { |
| | 1093 | IrInstructionArrayLen *instruction = ir_build_instruction<IrInstructionArrayLen>(irb, source_node); |
| | 1094 | instruction->array_value = array_value; |
| | 1095 | |
| | 1096 | ir_ref_instruction(array_value); |
| | 1097 | |
| | 1098 | return &instruction->base; |
| | 1099 | } |
| | 1100 | |
| | 1101 | static IrInstruction *ir_build_array_len_from(IrBuilder *irb, IrInstruction *old_instruction, |
| | 1102 | IrInstruction *array_value) |
| | 1103 | { |
| | 1104 | IrInstruction *new_instruction = ir_build_array_len(irb, old_instruction->source_node, array_value); |
| | 1105 | ir_link_new_instruction(new_instruction, old_instruction); |
| | 1106 | return new_instruction; |
| | 1107 | } |
| | 1108 | |
| 1090 | static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, BlockContext *outer_block, | 1109 | static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, BlockContext *outer_block, |
| 1091 | bool gen_error_defers, bool gen_maybe_defers) | 1110 | bool gen_error_defers, bool gen_maybe_defers) |
| 1092 | { | 1111 | { |
| ... | @@ -1376,7 +1395,7 @@ static IrInstruction *ir_gen_null_literal(IrBuilder *irb, AstNode *node) { | ... | @@ -1376,7 +1395,7 @@ static IrInstruction *ir_gen_null_literal(IrBuilder *irb, AstNode *node) { |
| 1376 | static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstNode *decl_node, | 1395 | static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstNode *decl_node, |
| 1377 | LValPurpose lval, BlockContext *scope) | 1396 | LValPurpose lval, BlockContext *scope) |
| 1378 | { | 1397 | { |
| 1379 | resolve_top_level_decl(irb->codegen, decl_node, lval); | 1398 | resolve_top_level_decl(irb->codegen, decl_node, lval != LValPurposeNone); |
| 1380 | TopLevelDecl *tld = get_as_top_level_decl(decl_node); | 1399 | TopLevelDecl *tld = get_as_top_level_decl(decl_node); |
| 1381 | if (tld->resolution == TldResolutionInvalid) | 1400 | if (tld->resolution == TldResolutionInvalid) |
| 1382 | return irb->codegen->invalid_instruction; | 1401 | return irb->codegen->invalid_instruction; |
| ... | @@ -1492,15 +1511,16 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, AstNode *node, LValPur | ... | @@ -1492,15 +1511,16 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, AstNode *node, LValPur |
| 1492 | AstNode *container_ref_node = node->data.field_access_expr.struct_expr; | 1511 | AstNode *container_ref_node = node->data.field_access_expr.struct_expr; |
| 1493 | Buf *field_name = node->data.field_access_expr.field_name; | 1512 | Buf *field_name = node->data.field_access_expr.field_name; |
| 1494 | | 1513 | |
| 1495 | IrInstruction *container_ref_instruction = ir_gen_node(irb, container_ref_node, node->block_context); | 1514 | IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, node->block_context, |
| | 1515 | LValPurposeAddressOf); |
| 1496 | if (container_ref_instruction == irb->codegen->invalid_instruction) | 1516 | if (container_ref_instruction == irb->codegen->invalid_instruction) |
| 1497 | return container_ref_instruction; | 1517 | return container_ref_instruction; |
| 1498 | | 1518 | |
| 1499 | if (lval == LValPurposeNone) { | 1519 | IrInstruction *ptr_instruction = ir_build_field_ptr(irb, node, container_ref_instruction, field_name); |
| 1500 | return ir_build_read_field(irb, node, container_ref_instruction, field_name); | 1520 | if (lval != LValPurposeNone) |
| 1501 | } else { | 1521 | return ptr_instruction; |
| 1502 | return ir_build_field_ptr(irb, node, container_ref_instruction, field_name); | 1522 | |
| 1503 | } | 1523 | return ir_build_load_ptr(irb, node, ptr_instruction); |
| 1504 | } | 1524 | } |
| 1505 | | 1525 | |
| 1506 | static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { | 1526 | static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { |
| ... | @@ -1628,6 +1648,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { | ... | @@ -1628,6 +1648,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { |
| 1628 | | 1648 | |
| 1629 | return ir_build_static_eval(irb, node, arg0_value); | 1649 | return ir_build_static_eval(irb, node, arg0_value); |
| 1630 | } | 1650 | } |
| | 1651 | case BuiltinFnIdImport: |
| | 1652 | { |
| | 1653 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| | 1654 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context); |
| | 1655 | if (arg0_value == irb->codegen->invalid_instruction) |
| | 1656 | return arg0_value; |
| | 1657 | |
| | 1658 | if (node->block_context->fn_entry) { |
| | 1659 | add_node_error(irb->codegen, node, buf_sprintf("import valid only at top level scope")); |
| | 1660 | return irb->codegen->invalid_instruction; |
| | 1661 | } |
| | 1662 | |
| | 1663 | return ir_build_import(irb, node, arg0_value); |
| | 1664 | } |
| 1631 | case BuiltinFnIdMemcpy: | 1665 | case BuiltinFnIdMemcpy: |
| 1632 | case BuiltinFnIdMemset: | 1666 | case BuiltinFnIdMemset: |
| 1633 | case BuiltinFnIdAlignof: | 1667 | case BuiltinFnIdAlignof: |
| ... | @@ -1642,7 +1676,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { | ... | @@ -1642,7 +1676,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { |
| 1642 | case BuiltinFnIdCDefine: | 1676 | case BuiltinFnIdCDefine: |
| 1643 | case BuiltinFnIdCUndef: | 1677 | case BuiltinFnIdCUndef: |
| 1644 | case BuiltinFnIdCompileErr: | 1678 | case BuiltinFnIdCompileErr: |
| 1645 | case BuiltinFnIdImport: | | |
| 1646 | case BuiltinFnIdCImport: | 1679 | case BuiltinFnIdCImport: |
| 1647 | case BuiltinFnIdErrName: | 1680 | case BuiltinFnIdErrName: |
| 1648 | case BuiltinFnIdBreakpoint: | 1681 | case BuiltinFnIdBreakpoint: |
| ... | @@ -1978,7 +2011,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -1978,7 +2011,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) { |
| 1978 | IrBasicBlock *end_block = ir_build_basic_block(irb, "ForEnd"); | 2011 | IrBasicBlock *end_block = ir_build_basic_block(irb, "ForEnd"); |
| 1979 | IrBasicBlock *continue_block = ir_build_basic_block(irb, "ForContinue"); | 2012 | IrBasicBlock *continue_block = ir_build_basic_block(irb, "ForContinue"); |
| 1980 | | 2013 | |
| 1981 | IrInstruction *len_val = ir_build_read_field(irb, node, array_val, irb->codegen->len_buf); | 2014 | IrInstruction *len_val = ir_build_array_len(irb, node, array_val); |
| 1982 | ir_build_br(irb, node, cond_block, is_inline); | 2015 | ir_build_br(irb, node, cond_block, is_inline); |
| 1983 | | 2016 | |
| 1984 | ir_set_cursor_at_end(irb, cond_block); | 2017 | ir_set_cursor_at_end(irb, cond_block); |
| ... | @@ -2846,7 +2879,9 @@ static ConstExprValue *ir_build_const_from(IrAnalyze *ira, IrInstruction *old_in | ... | @@ -2846,7 +2879,9 @@ static ConstExprValue *ir_build_const_from(IrAnalyze *ira, IrInstruction *old_in |
| 2846 | var_ptr_instruction->var = old_var_ptr_instruction->var; | 2879 | var_ptr_instruction->var = old_var_ptr_instruction->var; |
| 2847 | new_instruction = &var_ptr_instruction->base; | 2880 | new_instruction = &var_ptr_instruction->base; |
| 2848 | } else if (old_instruction->id == IrInstructionIdFieldPtr) { | 2881 | } else if (old_instruction->id == IrInstructionIdFieldPtr) { |
| 2849 | zig_panic("TODO"); | 2882 | IrInstructionFieldPtr *field_ptr_instruction = ir_create_instruction<IrInstructionFieldPtr>(ira->new_irb.exec, |
| | 2883 | old_instruction->source_node); |
| | 2884 | new_instruction = &field_ptr_instruction->base; |
| 2850 | } else if (old_instruction->id == IrInstructionIdElemPtr) { | 2885 | } else if (old_instruction->id == IrInstructionIdElemPtr) { |
| 2851 | IrInstructionElemPtr *elem_ptr_instruction = ir_create_instruction<IrInstructionElemPtr>(ira->new_irb.exec, | 2886 | IrInstructionElemPtr *elem_ptr_instruction = ir_create_instruction<IrInstructionElemPtr>(ira->new_irb.exec, |
| 2852 | old_instruction->source_node); | 2887 | old_instruction->source_node); |
| ... | @@ -2868,6 +2903,17 @@ static TypeTableEntry *ir_analyze_void(IrAnalyze *ira, IrInstruction *instructio | ... | @@ -2868,6 +2903,17 @@ static TypeTableEntry *ir_analyze_void(IrAnalyze *ira, IrInstruction *instructio |
| 2868 | return ira->codegen->builtin_types.entry_void; | 2903 | return ira->codegen->builtin_types.entry_void; |
| 2869 | } | 2904 | } |
| 2870 | | 2905 | |
| | 2906 | static TypeTableEntry *ir_analyze_const_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| | 2907 | ConstExprValue *pointee, TypeTableEntry *pointee_type, bool depends_on_compile_var) |
| | 2908 | { |
| | 2909 | TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, pointee_type, true); |
| | 2910 | ConstExprValue *const_val = ir_build_const_from(ira, instruction, |
| | 2911 | depends_on_compile_var || pointee->depends_on_compile_var); |
| | 2912 | const_val->data.x_ptr.base_ptr = pointee; |
| | 2913 | const_val->data.x_ptr.index = SIZE_MAX; |
| | 2914 | return ptr_type; |
| | 2915 | } |
| | 2916 | |
| 2871 | static TypeTableEntry *ir_analyze_const_usize(IrAnalyze *ira, IrInstruction *instruction, uint64_t value, | 2917 | static TypeTableEntry *ir_analyze_const_usize(IrAnalyze *ira, IrInstruction *instruction, uint64_t value, |
| 2872 | bool depends_on_compile_var) | 2918 | bool depends_on_compile_var) |
| 2873 | { | 2919 | { |
| ... | @@ -2889,9 +2935,6 @@ static TypeTableEntry *ir_resolve_type_lval(IrAnalyze *ira, IrInstruction *type_ | ... | @@ -2889,9 +2935,6 @@ static TypeTableEntry *ir_resolve_type_lval(IrAnalyze *ira, IrInstruction *type_ |
| 2889 | if (lval != LValPurposeNone) | 2935 | if (lval != LValPurposeNone) |
| 2890 | zig_panic("TODO"); | 2936 | zig_panic("TODO"); |
| 2891 | | 2937 | |
| 2892 | if (type_value == ira->codegen->invalid_instruction) | | |
| 2893 | return ira->codegen->builtin_types.entry_invalid; | | |
| 2894 | | | |
| 2895 | if (type_value->type_entry->id == TypeTableEntryIdInvalid) | 2938 | if (type_value->type_entry->id == TypeTableEntryIdInvalid) |
| 2896 | return ira->codegen->builtin_types.entry_invalid; | 2939 | return ira->codegen->builtin_types.entry_invalid; |
| 2897 | | 2940 | |
| ... | @@ -3810,7 +3853,7 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction | ... | @@ -3810,7 +3853,7 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction |
| 3810 | } | 3853 | } |
| 3811 | | 3854 | |
| 3812 | ir_build_call_from(&ira->new_irb, &call_instruction->base, | 3855 | ir_build_call_from(&ira->new_irb, &call_instruction->base, |
| 3813 | call_instruction->fn, call_instruction->arg_count, casted_args); | 3856 | fn_ref, call_instruction->arg_count, casted_args); |
| 3814 | | 3857 | |
| 3815 | return ir_finish_anal(ira, fn_type->data.fn.fn_type_id.return_type); | 3858 | return ir_finish_anal(ira, fn_type->data.fn.fn_type_id.return_type); |
| 3816 | } else { | 3859 | } else { |
| ... | @@ -4286,14 +4329,11 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP | ... | @@ -4286,14 +4329,11 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP |
| 4286 | return resolved_type; | 4329 | return resolved_type; |
| 4287 | } | 4330 | } |
| 4288 | | 4331 | |
| 4289 | static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *var_ptr_instruction) { | 4332 | static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruction, VariableTableEntry *var) { |
| 4290 | VariableTableEntry *var = var_ptr_instruction->var; | | |
| 4291 | assert(var->type); | 4333 | assert(var->type); |
| 4292 | if (var->type->id == TypeTableEntryIdInvalid) | 4334 | if (var->type->id == TypeTableEntryIdInvalid) |
| 4293 | return var->type; | 4335 | return var->type; |
| 4294 | | 4336 | |
| 4295 | TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, var->type, false); | | |
| 4296 | | | |
| 4297 | ConstExprValue *mem_slot = nullptr; | 4337 | ConstExprValue *mem_slot = nullptr; |
| 4298 | if (var->block_context->fn_entry) { | 4338 | if (var->block_context->fn_entry) { |
| 4299 | // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing. | 4339 | // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing. |
| ... | @@ -4302,23 +4342,23 @@ static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -4302,23 +4342,23 @@ static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstruct |
| 4302 | } else if (var->src_is_const) { | 4342 | } else if (var->src_is_const) { |
| 4303 | AstNode *var_decl_node = var->decl_node; | 4343 | AstNode *var_decl_node = var->decl_node; |
| 4304 | assert(var_decl_node->type == NodeTypeVariableDeclaration); | 4344 | assert(var_decl_node->type == NodeTypeVariableDeclaration); |
| 4305 | mem_slot = &get_resolved_expr(var_decl_node->data.variable_declaration.expr)->instruction->static_value; | 4345 | mem_slot = &var_decl_node->data.variable_declaration.top_level_decl.value->static_value; |
| 4306 | assert(mem_slot->special != ConstValSpecialRuntime); | 4346 | assert(mem_slot->special != ConstValSpecialRuntime); |
| 4307 | } | 4347 | } |
| 4308 | | 4348 | |
| 4309 | if (mem_slot && mem_slot->special != ConstValSpecialRuntime) { | 4349 | if (mem_slot && mem_slot->special != ConstValSpecialRuntime) { |
| 4310 | ConstExprValue *out_val = ir_build_const_from(ira, &var_ptr_instruction->base, | 4350 | return ir_analyze_const_ptr(ira, instruction, mem_slot, var->type, false); |
| 4311 | mem_slot->depends_on_compile_var); | | |
| 4312 | | | |
| 4313 | out_val->data.x_ptr.base_ptr = mem_slot; | | |
| 4314 | out_val->data.x_ptr.index = SIZE_MAX; | | |
| 4315 | return ptr_type; | | |
| 4316 | } else { | 4351 | } else { |
| 4317 | ir_build_var_ptr_from(&ira->new_irb, &var_ptr_instruction->base, var); | 4352 | ir_build_var_ptr_from(&ira->new_irb, instruction, var); |
| 4318 | return ptr_type; | 4353 | return get_pointer_to_type(ira->codegen, var->type, false); |
| 4319 | } | 4354 | } |
| 4320 | } | 4355 | } |
| 4321 | | 4356 | |
| | 4357 | static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *var_ptr_instruction) { |
| | 4358 | VariableTableEntry *var = var_ptr_instruction->var; |
| | 4359 | return ir_analyze_var_ptr(ira, &var_ptr_instruction->base, var); |
| | 4360 | } |
| | 4361 | |
| 4322 | static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) { | 4362 | static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) { |
| 4323 | IrInstruction *array_ptr = elem_ptr_instruction->array_ptr->other; | 4363 | IrInstruction *array_ptr = elem_ptr_instruction->array_ptr->other; |
| 4324 | if (array_ptr->type_entry->id == TypeTableEntryIdInvalid) | 4364 | if (array_ptr->type_entry->id == TypeTableEntryIdInvalid) |
| ... | @@ -4483,108 +4523,146 @@ static TypeTableEntry *ir_analyze_container_member_access(IrAnalyze *ira, Buf *f | ... | @@ -4483,108 +4523,146 @@ static TypeTableEntry *ir_analyze_container_member_access(IrAnalyze *ira, Buf *f |
| 4483 | } | 4523 | } |
| 4484 | } | 4524 | } |
| 4485 | | 4525 | |
| 4486 | static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstructionFieldPtr *field_ptr_instruction) { | 4526 | static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, AstNode *decl_node, |
| 4487 | IrInstruction *container_ptr = field_ptr_instruction->container_ptr->other; | 4527 | bool depends_on_compile_var) |
| 4488 | Buf *field_name = field_ptr_instruction->field_name; | 4528 | { |
| | 4529 | bool pointer_only = false; |
| | 4530 | resolve_top_level_decl(ira->codegen, decl_node, pointer_only); |
| | 4531 | TopLevelDecl *tld = get_as_top_level_decl(decl_node); |
| | 4532 | if (tld->resolution == TldResolutionInvalid) |
| | 4533 | return ira->codegen->builtin_types.entry_invalid; |
| 4489 | | 4534 | |
| 4490 | TypeTableEntry *container_type = container_ptr->type_entry; | 4535 | if (decl_node->type == NodeTypeVariableDeclaration) { |
| 4491 | if (container_type->id == TypeTableEntryIdInvalid) { | 4536 | VariableTableEntry *var = decl_node->data.variable_declaration.variable; |
| 4492 | return container_type; | 4537 | return ir_analyze_var_ptr(ira, source_instruction, var); |
| 4493 | } else if (is_container_ref(container_type)) { | 4538 | } else if (decl_node->type == NodeTypeFnProto) { |
| 4494 | return ir_analyze_container_member_access(ira, field_name, field_ptr_instruction, container_type); | 4539 | FnTableEntry *fn_entry = decl_node->data.fn_proto.fn_table_entry; |
| 4495 | } else if (container_type->id == TypeTableEntryIdArray) { | 4540 | assert(fn_entry->type_entry); |
| 4496 | if (buf_eql_str(field_name, "len")) { | | |
| 4497 | add_node_error(ira->codegen, field_ptr_instruction->base.source_node, | | |
| 4498 | buf_sprintf("pointer to array length not available")); | | |
| 4499 | return ira->codegen->builtin_types.entry_invalid; | | |
| 4500 | } else { | | |
| 4501 | add_node_error(ira->codegen, field_ptr_instruction->base.source_node, | | |
| 4502 | buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), | | |
| 4503 | buf_ptr(&container_type->name))); | | |
| 4504 | return ira->codegen->builtin_types.entry_invalid; | | |
| 4505 | } | | |
| 4506 | } else if (container_type->id == TypeTableEntryIdMetaType) { | | |
| 4507 | TypeTableEntry *child_type = ir_resolve_type(ira, container_ptr); | | |
| 4508 | | 4541 | |
| 4509 | if (child_type->id == TypeTableEntryIdInvalid) { | 4542 | // TODO instead of allocating this every time, put it in the tld value and we can reference |
| 4510 | return ira->codegen->builtin_types.entry_invalid; | 4543 | // the same one every time |
| 4511 | } else if (child_type->id == TypeTableEntryIdEnum) { | 4544 | ConstExprValue *const_val = allocate<ConstExprValue>(1); |
| 4512 | zig_panic("TODO enum type field"); | 4545 | const_val->special = ConstValSpecialStatic; |
| 4513 | } else if (child_type->id == TypeTableEntryIdStruct) { | 4546 | if (fn_entry->type_entry->id == TypeTableEntryIdGenericFn) { |
| 4514 | zig_panic("TODO struct type field"); | 4547 | const_val->data.x_type = fn_entry->type_entry; |
| 4515 | } else if (child_type->id == TypeTableEntryIdPureError) { | | |
| 4516 | zig_panic("TODO error type field"); | | |
| 4517 | } else if (child_type->id == TypeTableEntryIdInt) { | | |
| 4518 | zig_panic("TODO integer type field"); | | |
| 4519 | } else { | 4548 | } else { |
| 4520 | add_node_error(ira->codegen, field_ptr_instruction->base.source_node, | 4549 | const_val->data.x_fn = fn_entry; |
| 4521 | buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); | | |
| 4522 | return ira->codegen->builtin_types.entry_invalid; | | |
| 4523 | } | 4550 | } |
| 4524 | } else if (container_type->id == TypeTableEntryIdNamespace) { | 4551 | |
| 4525 | zig_panic("TODO namespace field access"); | 4552 | return ir_analyze_const_ptr(ira, source_instruction, const_val, fn_entry->type_entry, depends_on_compile_var); |
| | 4553 | } else if (decl_node->type == NodeTypeContainerDecl) { |
| | 4554 | zig_panic("TODO"); |
| | 4555 | //ConstExprValue *out_val = ir_build_const_from(ira, source_instruction, depends_on_compile_var); |
| | 4556 | //if (decl_node->data.struct_decl.generic_params.length > 0) { |
| | 4557 | // TypeTableEntry *type_entry = decl_node->data.struct_decl.generic_fn_type; |
| | 4558 | // assert(type_entry); |
| | 4559 | // out_val->data.x_type = type_entry; |
| | 4560 | // return type_entry; |
| | 4561 | //} else { |
| | 4562 | // out_val->data.x_type = decl_node->data.struct_decl.type_entry; |
| | 4563 | // return ira->codegen->builtin_types.entry_type; |
| | 4564 | //} |
| | 4565 | } else if (decl_node->type == NodeTypeTypeDecl) { |
| | 4566 | zig_panic("TODO"); |
| | 4567 | //ConstExprValue *out_val = ir_build_const_from(ira, source_instruction, depends_on_compile_var); |
| | 4568 | //out_val->data.x_type = decl_node->data.type_decl.child_type_entry; |
| | 4569 | //return ira->codegen->builtin_types.entry_type; |
| 4526 | } else { | 4570 | } else { |
| 4527 | add_node_error(ira->codegen, field_ptr_instruction->base.source_node, | 4571 | zig_unreachable(); |
| 4528 | buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); | | |
| 4529 | return ira->codegen->builtin_types.entry_invalid; | | |
| 4530 | } | 4572 | } |
| 4531 | } | 4573 | } |
| 4532 | | 4574 | |
| 4533 | static TypeTableEntry *ir_analyze_read_field_as_ptr_load(IrAnalyze *ira, | 4575 | static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstructionFieldPtr *field_ptr_instruction) { |
| 4534 | IrInstructionReadField *read_field_instruction) | 4576 | IrInstruction *container_ptr = field_ptr_instruction->container_ptr->other; |
| 4535 | { | 4577 | if (container_ptr->type_entry->id == TypeTableEntryIdInvalid) |
| 4536 | IrInstruction *old_field_ptr_inst = ir_build_field_ptr(&ira->old_irb, read_field_instruction->base.source_node, | 4578 | return ira->codegen->builtin_types.entry_invalid; |
| 4537 | read_field_instruction->container_ptr, read_field_instruction->field_name); | | |
| 4538 | IrInstruction *old_load_ptr_inst = ir_build_load_ptr(&ira->old_irb, read_field_instruction->base.source_node, | | |
| 4539 | old_field_ptr_inst); | | |
| 4540 | ir_analyze_instruction(ira, old_field_ptr_inst); | | |
| 4541 | TypeTableEntry *result_type = ir_analyze_instruction(ira, old_load_ptr_inst); | | |
| 4542 | read_field_instruction->base.other = old_load_ptr_inst->other; | | |
| 4543 | return result_type; | | |
| 4544 | } | | |
| 4545 | | 4579 | |
| 4546 | static TypeTableEntry *ir_analyze_instruction_read_field(IrAnalyze *ira, | 4580 | assert(container_ptr->type_entry->id == TypeTableEntryIdPointer); |
| 4547 | IrInstructionReadField *read_field_instruction) | 4581 | TypeTableEntry *container_type = container_ptr->type_entry->data.pointer.child_type; |
| 4548 | { | 4582 | |
| 4549 | IrInstruction *container_ptr = read_field_instruction->container_ptr->other; | 4583 | Buf *field_name = field_ptr_instruction->field_name; |
| 4550 | Buf *field_name = read_field_instruction->field_name; | 4584 | AstNode *source_node = field_ptr_instruction->base.source_node; |
| 4551 | | 4585 | |
| 4552 | TypeTableEntry *container_type = container_ptr->type_entry; | | |
| 4553 | if (container_type->id == TypeTableEntryIdInvalid) { | 4586 | if (container_type->id == TypeTableEntryIdInvalid) { |
| 4554 | return container_type; | 4587 | return container_type; |
| 4555 | } else if (is_container_ref(container_type)) { | 4588 | } else if (is_container_ref(container_type)) { |
| 4556 | return ir_analyze_read_field_as_ptr_load(ira, read_field_instruction); | 4589 | return ir_analyze_container_member_access(ira, field_name, field_ptr_instruction, container_type); |
| 4557 | } else if (container_type->id == TypeTableEntryIdArray) { | 4590 | } else if (container_type->id == TypeTableEntryIdArray) { |
| 4558 | if (buf_eql_str(field_name, "len")) { | 4591 | if (buf_eql_str(field_name, "len")) { |
| 4559 | return ir_analyze_const_usize(ira, &read_field_instruction->base, container_type->data.array.len, false); | 4592 | ConstExprValue *len_val = allocate<ConstExprValue>(1); |
| | 4593 | len_val->special = ConstValSpecialStatic; |
| | 4594 | bignum_init_unsigned(&len_val->data.x_bignum, container_type->data.array.len); |
| | 4595 | |
| | 4596 | TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize; |
| | 4597 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, len_val, usize, false); |
| 4560 | } else { | 4598 | } else { |
| 4561 | add_node_error(ira->codegen, read_field_instruction->base.source_node, | 4599 | add_node_error(ira->codegen, source_node, |
| 4562 | buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), | 4600 | buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), |
| 4563 | buf_ptr(&container_type->name))); | 4601 | buf_ptr(&container_type->name))); |
| 4564 | return ira->codegen->builtin_types.entry_invalid; | 4602 | return ira->codegen->builtin_types.entry_invalid; |
| 4565 | } | 4603 | } |
| 4566 | } else if (container_type->id == TypeTableEntryIdMetaType) { | 4604 | } else if (container_type->id == TypeTableEntryIdMetaType) { |
| 4567 | TypeTableEntry *child_type = ir_resolve_type(ira, container_ptr); | 4605 | zig_panic("TODO type field access"); |
| 4568 | | 4606 | //TypeTableEntry *child_type = ir_resolve_type(ira, container_ptr); |
| 4569 | if (child_type->id == TypeTableEntryIdInvalid) { | 4607 | |
| | 4608 | //if (child_type->id == TypeTableEntryIdInvalid) { |
| | 4609 | // return ira->codegen->builtin_types.entry_invalid; |
| | 4610 | //} else if (child_type->id == TypeTableEntryIdEnum) { |
| | 4611 | // zig_panic("TODO enum type field"); |
| | 4612 | //} else if (child_type->id == TypeTableEntryIdStruct) { |
| | 4613 | // zig_panic("TODO struct type field"); |
| | 4614 | //} else if (child_type->id == TypeTableEntryIdPureError) { |
| | 4615 | // zig_panic("TODO error type field"); |
| | 4616 | //} else if (child_type->id == TypeTableEntryIdInt) { |
| | 4617 | // zig_panic("TODO integer type field"); |
| | 4618 | //} else { |
| | 4619 | // add_node_error(ira->codegen, source_node, |
| | 4620 | // buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); |
| | 4621 | // return ira->codegen->builtin_types.entry_invalid; |
| | 4622 | //} |
| | 4623 | } else if (container_type->id == TypeTableEntryIdNamespace) { |
| | 4624 | ConstExprValue *container_ptr_val = ir_resolve_const(ira, container_ptr); |
| | 4625 | if (!container_ptr_val) |
| 4570 | return ira->codegen->builtin_types.entry_invalid; | 4626 | return ira->codegen->builtin_types.entry_invalid; |
| 4571 | } else if (child_type->id == TypeTableEntryIdEnum) { | 4627 | |
| 4572 | zig_panic("TODO enum type field"); | 4628 | ConstExprValue *namespace_val = const_ptr_pointee(container_ptr_val); |
| 4573 | } else if (child_type->id == TypeTableEntryIdStruct) { | 4629 | assert(namespace_val->special == ConstValSpecialStatic); |
| 4574 | zig_panic("TODO struct type field"); | 4630 | |
| 4575 | } else if (child_type->id == TypeTableEntryIdPureError) { | 4631 | ImportTableEntry *namespace_import = namespace_val->data.x_import; |
| 4576 | zig_panic("TODO error type field"); | 4632 | |
| 4577 | } else if (child_type->id == TypeTableEntryIdInt) { | 4633 | bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var; |
| 4578 | zig_panic("TODO integer type field"); | 4634 | AstNode *decl_node = find_decl(namespace_import->block_context, field_name); |
| | 4635 | if (!decl_node) { |
| | 4636 | // we must now resolve all the use decls |
| | 4637 | for (size_t i = 0; i < namespace_import->use_decls.length; i += 1) { |
| | 4638 | AstNode *use_decl_node = namespace_import->use_decls.at(i); |
| | 4639 | TopLevelDecl *tld = get_as_top_level_decl(use_decl_node); |
| | 4640 | if (tld->resolution == TldResolutionUnresolved) { |
| | 4641 | preview_use_decl(ira->codegen, use_decl_node); |
| | 4642 | } |
| | 4643 | resolve_use_decl(ira->codegen, use_decl_node); |
| | 4644 | } |
| | 4645 | decl_node = find_decl(namespace_import->block_context, field_name); |
| | 4646 | } |
| | 4647 | if (decl_node) { |
| | 4648 | TopLevelDecl *tld = get_as_top_level_decl(decl_node); |
| | 4649 | if (tld->visib_mod == VisibModPrivate && |
| | 4650 | decl_node->owner != source_node->owner) |
| | 4651 | { |
| | 4652 | ErrorMsg *msg = add_node_error(ira->codegen, source_node, |
| | 4653 | buf_sprintf("'%s' is private", buf_ptr(field_name))); |
| | 4654 | add_error_note(ira->codegen, msg, decl_node, buf_sprintf("declared here")); |
| | 4655 | return ira->codegen->builtin_types.entry_invalid; |
| | 4656 | } |
| | 4657 | return ir_analyze_decl_ref(ira, &field_ptr_instruction->base, decl_node, depends_on_compile_var); |
| 4579 | } else { | 4658 | } else { |
| 4580 | add_node_error(ira->codegen, read_field_instruction->base.source_node, | 4659 | const char *import_name = namespace_import->path ? buf_ptr(namespace_import->path) : "(C import)"; |
| 4581 | buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); | 4660 | add_node_error(ira->codegen, source_node, |
| | 4661 | buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), import_name)); |
| 4582 | return ira->codegen->builtin_types.entry_invalid; | 4662 | return ira->codegen->builtin_types.entry_invalid; |
| 4583 | } | 4663 | } |
| 4584 | } else if (container_type->id == TypeTableEntryIdNamespace) { | | |
| 4585 | zig_panic("TODO namespace field access"); | | |
| 4586 | } else { | 4664 | } else { |
| 4587 | add_node_error(ira->codegen, read_field_instruction->base.source_node, | 4665 | add_node_error(ira->codegen, field_ptr_instruction->base.source_node, |
| 4588 | buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); | 4666 | buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); |
| 4589 | return ira->codegen->builtin_types.entry_invalid; | 4667 | return ira->codegen->builtin_types.entry_invalid; |
| 4590 | } | 4668 | } |
| ... | @@ -4610,7 +4688,7 @@ static TypeTableEntry *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -4610,7 +4688,7 @@ static TypeTableEntry *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruc |
| 4610 | return child_type; | 4688 | return child_type; |
| 4611 | } else { | 4689 | } else { |
| 4612 | add_node_error(ira->codegen, load_ptr_instruction->base.source_node, | 4690 | add_node_error(ira->codegen, load_ptr_instruction->base.source_node, |
| 4613 | buf_sprintf("indirection requires pointer operand ('%s' invalid)", | 4691 | buf_sprintf("attempt to dereference non pointer type '%s'", |
| 4614 | buf_ptr(&type_entry->name))); | 4692 | buf_ptr(&type_entry->name))); |
| 4615 | return ira->codegen->builtin_types.entry_invalid; | 4693 | return ira->codegen->builtin_types.entry_invalid; |
| 4616 | } | 4694 | } |
| ... | @@ -5413,6 +5491,110 @@ static TypeTableEntry *ir_analyze_instruction_static_eval(IrAnalyze *ira, | ... | @@ -5413,6 +5491,110 @@ static TypeTableEntry *ir_analyze_instruction_static_eval(IrAnalyze *ira, |
| 5413 | return value->type_entry; | 5491 | return value->type_entry; |
| 5414 | } | 5492 | } |
| 5415 | | 5493 | |
| | 5494 | static TypeTableEntry *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImport *import_instruction) { |
| | 5495 | IrInstruction *name_value = import_instruction->name->other; |
| | 5496 | Buf *import_target_str = ir_resolve_str(ira, name_value); |
| | 5497 | if (!import_target_str) |
| | 5498 | return ira->codegen->builtin_types.entry_invalid; |
| | 5499 | bool depends_on_compile_var = name_value->static_value.depends_on_compile_var; |
| | 5500 | |
| | 5501 | AstNode *source_node = import_instruction->base.source_node; |
| | 5502 | ImportTableEntry *import = source_node->owner; |
| | 5503 | |
| | 5504 | Buf *import_target_path; |
| | 5505 | Buf *search_dir; |
| | 5506 | assert(import->package); |
| | 5507 | PackageTableEntry *target_package; |
| | 5508 | auto package_entry = import->package->package_table.maybe_get(import_target_str); |
| | 5509 | if (package_entry) { |
| | 5510 | target_package = package_entry->value; |
| | 5511 | import_target_path = &target_package->root_src_path; |
| | 5512 | search_dir = &target_package->root_src_dir; |
| | 5513 | } else { |
| | 5514 | // try it as a filename |
| | 5515 | target_package = import->package; |
| | 5516 | import_target_path = import_target_str; |
| | 5517 | search_dir = &import->package->root_src_dir; |
| | 5518 | } |
| | 5519 | |
| | 5520 | Buf full_path = BUF_INIT; |
| | 5521 | os_path_join(search_dir, import_target_path, &full_path); |
| | 5522 | |
| | 5523 | Buf *import_code = buf_alloc(); |
| | 5524 | Buf *abs_full_path = buf_alloc(); |
| | 5525 | int err; |
| | 5526 | if ((err = os_path_real(&full_path, abs_full_path))) { |
| | 5527 | if (err == ErrorFileNotFound) { |
| | 5528 | add_node_error(ira->codegen, source_node, |
| | 5529 | buf_sprintf("unable to find '%s'", buf_ptr(import_target_path))); |
| | 5530 | return ira->codegen->builtin_types.entry_invalid; |
| | 5531 | } else { |
| | 5532 | ira->codegen->error_during_imports = true; |
| | 5533 | add_node_error(ira->codegen, source_node, |
| | 5534 | buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err))); |
| | 5535 | return ira->codegen->builtin_types.entry_invalid; |
| | 5536 | } |
| | 5537 | } |
| | 5538 | |
| | 5539 | auto import_entry = ira->codegen->import_table.maybe_get(abs_full_path); |
| | 5540 | if (import_entry) { |
| | 5541 | ConstExprValue *out_val = ir_build_const_from(ira, &import_instruction->base, depends_on_compile_var); |
| | 5542 | out_val->data.x_import = import_entry->value; |
| | 5543 | return ira->codegen->builtin_types.entry_namespace; |
| | 5544 | } |
| | 5545 | |
| | 5546 | if ((err = os_fetch_file_path(abs_full_path, import_code))) { |
| | 5547 | if (err == ErrorFileNotFound) { |
| | 5548 | add_node_error(ira->codegen, source_node, |
| | 5549 | buf_sprintf("unable to find '%s'", buf_ptr(import_target_path))); |
| | 5550 | return ira->codegen->builtin_types.entry_invalid; |
| | 5551 | } else { |
| | 5552 | add_node_error(ira->codegen, source_node, |
| | 5553 | buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err))); |
| | 5554 | return ira->codegen->builtin_types.entry_invalid; |
| | 5555 | } |
| | 5556 | } |
| | 5557 | ImportTableEntry *target_import = add_source_file(ira->codegen, target_package, |
| | 5558 | abs_full_path, search_dir, import_target_path, import_code); |
| | 5559 | |
| | 5560 | scan_decls(ira->codegen, target_import, target_import->block_context, target_import->root); |
| | 5561 | |
| | 5562 | ConstExprValue *out_val = ir_build_const_from(ira, &import_instruction->base, depends_on_compile_var); |
| | 5563 | out_val->data.x_import = target_import; |
| | 5564 | return ira->codegen->builtin_types.entry_namespace; |
| | 5565 | |
| | 5566 | } |
| | 5567 | |
| | 5568 | static TypeTableEntry *ir_analyze_instruction_array_len(IrAnalyze *ira, |
| | 5569 | IrInstructionArrayLen *array_len_instruction) |
| | 5570 | { |
| | 5571 | IrInstruction *array_value = array_len_instruction->array_value->other; |
| | 5572 | TypeTableEntry *canon_type = get_underlying_type(array_value->type_entry); |
| | 5573 | if (canon_type->id == TypeTableEntryIdInvalid) { |
| | 5574 | return ira->codegen->builtin_types.entry_invalid; |
| | 5575 | } else if (canon_type->id == TypeTableEntryIdArray) { |
| | 5576 | bool depends_on_compile_var = array_value->static_value.depends_on_compile_var; |
| | 5577 | return ir_analyze_const_usize(ira, &array_len_instruction->base, |
| | 5578 | canon_type->data.array.len, depends_on_compile_var); |
| | 5579 | } else if (is_slice(canon_type)) { |
| | 5580 | if (array_value->static_value.special != ConstValSpecialRuntime) { |
| | 5581 | ConstExprValue *len_val = &array_value->static_value.data.x_struct.fields[slice_len_index]; |
| | 5582 | if (len_val->special != ConstValSpecialRuntime) { |
| | 5583 | bool depends_on_compile_var = len_val->depends_on_compile_var; |
| | 5584 | return ir_analyze_const_usize(ira, &array_len_instruction->base, |
| | 5585 | len_val->data.x_bignum.data.x_uint, depends_on_compile_var); |
| | 5586 | } |
| | 5587 | } |
| | 5588 | ir_build_array_len_from(&ira->new_irb, &array_len_instruction->base, array_value); |
| | 5589 | return ira->codegen->builtin_types.entry_usize; |
| | 5590 | } else { |
| | 5591 | add_node_error(ira->codegen, array_len_instruction->base.source_node, |
| | 5592 | buf_sprintf("type '%s' has no field 'len'", buf_ptr(&array_value->type_entry->name))); |
| | 5593 | // TODO if this is a typedecl, add error note showing the declaration of the type decl |
| | 5594 | return ira->codegen->builtin_types.entry_invalid; |
| | 5595 | } |
| | 5596 | } |
| | 5597 | |
| 5416 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { | 5598 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { |
| 5417 | switch (instruction->id) { | 5599 | switch (instruction->id) { |
| 5418 | case IrInstructionIdInvalid: | 5600 | case IrInstructionIdInvalid: |
| ... | @@ -5437,8 +5619,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -5437,8 +5619,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 5437 | return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction); | 5619 | return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction); |
| 5438 | case IrInstructionIdFieldPtr: | 5620 | case IrInstructionIdFieldPtr: |
| 5439 | return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction); | 5621 | return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction); |
| 5440 | case IrInstructionIdReadField: | | |
| 5441 | return ir_analyze_instruction_read_field(ira, (IrInstructionReadField *)instruction); | | |
| 5442 | case IrInstructionIdCall: | 5622 | case IrInstructionIdCall: |
| 5443 | return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction); | 5623 | return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction); |
| 5444 | case IrInstructionIdBr: | 5624 | case IrInstructionIdBr: |
| ... | @@ -5489,6 +5669,10 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -5489,6 +5669,10 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 5489 | return ir_analyze_instruction_enum_tag(ira, (IrInstructionEnumTag *)instruction); | 5669 | return ir_analyze_instruction_enum_tag(ira, (IrInstructionEnumTag *)instruction); |
| 5490 | case IrInstructionIdStaticEval: | 5670 | case IrInstructionIdStaticEval: |
| 5491 | return ir_analyze_instruction_static_eval(ira, (IrInstructionStaticEval *)instruction); | 5671 | return ir_analyze_instruction_static_eval(ira, (IrInstructionStaticEval *)instruction); |
| | 5672 | case IrInstructionIdImport: |
| | 5673 | return ir_analyze_instruction_import(ira, (IrInstructionImport *)instruction); |
| | 5674 | case IrInstructionIdArrayLen: |
| | 5675 | return ir_analyze_instruction_array_len(ira, (IrInstructionArrayLen *)instruction); |
| 5492 | case IrInstructionIdCast: | 5676 | case IrInstructionIdCast: |
| 5493 | case IrInstructionIdContainerInitList: | 5677 | case IrInstructionIdContainerInitList: |
| 5494 | case IrInstructionIdContainerInitFields: | 5678 | case IrInstructionIdContainerInitFields: |
| ... | @@ -5580,6 +5764,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -5580,6 +5764,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 5580 | case IrInstructionIdSetFnTest: | 5764 | case IrInstructionIdSetFnTest: |
| 5581 | case IrInstructionIdSetFnVisible: | 5765 | case IrInstructionIdSetFnVisible: |
| 5582 | case IrInstructionIdSetDebugSafety: | 5766 | case IrInstructionIdSetDebugSafety: |
| | 5767 | case IrInstructionIdImport: |
| 5583 | return true; | 5768 | return true; |
| 5584 | case IrInstructionIdPhi: | 5769 | case IrInstructionIdPhi: |
| 5585 | case IrInstructionIdUnOp: | 5770 | case IrInstructionIdUnOp: |
| ... | @@ -5595,7 +5780,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -5595,7 +5780,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 5595 | case IrInstructionIdTypeOf: | 5780 | case IrInstructionIdTypeOf: |
| 5596 | case IrInstructionIdToPtrType: | 5781 | case IrInstructionIdToPtrType: |
| 5597 | case IrInstructionIdPtrTypeChild: | 5782 | case IrInstructionIdPtrTypeChild: |
| 5598 | case IrInstructionIdReadField: | 5783 | case IrInstructionIdArrayLen: |
| 5599 | case IrInstructionIdStructFieldPtr: | 5784 | case IrInstructionIdStructFieldPtr: |
| 5600 | case IrInstructionIdArrayType: | 5785 | case IrInstructionIdArrayType: |
| 5601 | case IrInstructionIdSliceType: | 5786 | case IrInstructionIdSliceType: |
| ... | @@ -5666,81 +5851,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { | ... | @@ -5666,81 +5851,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { |
| 5666 | // } | 5851 | // } |
| 5667 | //} | 5852 | //} |
| 5668 | | 5853 | |
| 5669 | //static TypeTableEntry *analyze_import(CodeGen *g, ImportTableEntry *import, BlockContext *context, | | |
| 5670 | // AstNode *node) | | |
| 5671 | //{ | | |
| 5672 | // assert(node->type == NodeTypeFnCallExpr); | | |
| 5673 | // | | |
| 5674 | // if (context->fn_entry) { | | |
| 5675 | // add_node_error(g, node, buf_sprintf("@import invalid inside function bodies")); | | |
| 5676 | // return g->builtin_types.entry_invalid; | | |
| 5677 | // } | | |
| 5678 | // | | |
| 5679 | // AstNode *first_param_node = node->data.fn_call_expr.params.at(0); | | |
| 5680 | // Buf *import_target_str = resolve_const_expr_str(g, import, context, first_param_node->parent_field); | | |
| 5681 | // if (!import_target_str) { | | |
| 5682 | // return g->builtin_types.entry_invalid; | | |
| 5683 | // } | | |
| 5684 | // | | |
| 5685 | // Buf *import_target_path; | | |
| 5686 | // Buf *search_dir; | | |
| 5687 | // assert(import->package); | | |
| 5688 | // PackageTableEntry *target_package; | | |
| 5689 | // auto package_entry = import->package->package_table.maybe_get(import_target_str); | | |
| 5690 | // if (package_entry) { | | |
| 5691 | // target_package = package_entry->value; | | |
| 5692 | // import_target_path = &target_package->root_src_path; | | |
| 5693 | // search_dir = &target_package->root_src_dir; | | |
| 5694 | // } else { | | |
| 5695 | // // try it as a filename | | |
| 5696 | // target_package = import->package; | | |
| 5697 | // import_target_path = import_target_str; | | |
| 5698 | // search_dir = &import->package->root_src_dir; | | |
| 5699 | // } | | |
| 5700 | // | | |
| 5701 | // Buf full_path = BUF_INIT; | | |
| 5702 | // os_path_join(search_dir, import_target_path, &full_path); | | |
| 5703 | // | | |
| 5704 | // Buf *import_code = buf_alloc(); | | |
| 5705 | // Buf *abs_full_path = buf_alloc(); | | |
| 5706 | // int err; | | |
| 5707 | // if ((err = os_path_real(&full_path, abs_full_path))) { | | |
| 5708 | // if (err == ErrorFileNotFound) { | | |
| 5709 | // add_node_error(g, node, | | |
| 5710 | // buf_sprintf("unable to find '%s'", buf_ptr(import_target_path))); | | |
| 5711 | // return g->builtin_types.entry_invalid; | | |
| 5712 | // } else { | | |
| 5713 | // g->error_during_imports = true; | | |
| 5714 | // add_node_error(g, node, | | |
| 5715 | // buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err))); | | |
| 5716 | // return g->builtin_types.entry_invalid; | | |
| 5717 | // } | | |
| 5718 | // } | | |
| 5719 | // | | |
| 5720 | // auto import_entry = g->import_table.maybe_get(abs_full_path); | | |
| 5721 | // if (import_entry) { | | |
| 5722 | // return resolve_expr_const_val_as_import(g, node, import_entry->value); | | |
| 5723 | // } | | |
| 5724 | // | | |
| 5725 | // if ((err = os_fetch_file_path(abs_full_path, import_code))) { | | |
| 5726 | // if (err == ErrorFileNotFound) { | | |
| 5727 | // add_node_error(g, node, | | |
| 5728 | // buf_sprintf("unable to find '%s'", buf_ptr(import_target_path))); | | |
| 5729 | // return g->builtin_types.entry_invalid; | | |
| 5730 | // } else { | | |
| 5731 | // add_node_error(g, node, | | |
| 5732 | // buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err))); | | |
| 5733 | // return g->builtin_types.entry_invalid; | | |
| 5734 | // } | | |
| 5735 | // } | | |
| 5736 | // ImportTableEntry *target_import = add_source_file(g, target_package, | | |
| 5737 | // abs_full_path, search_dir, import_target_path, import_code); | | |
| 5738 | // | | |
| 5739 | // scan_decls(g, target_import, target_import->block_context, target_import->root); | | |
| 5740 | // | | |
| 5741 | // return resolve_expr_const_val_as_import(g, node, target_import); | | |
| 5742 | //} | | |
| 5743 | // | | |
| 5744 | //static TypeTableEntry *analyze_c_import(CodeGen *g, ImportTableEntry *parent_import, | 5854 | //static TypeTableEntry *analyze_c_import(CodeGen *g, ImportTableEntry *parent_import, |
| 5745 | // BlockContext *parent_context, AstNode *node) | 5855 | // BlockContext *parent_context, AstNode *node) |
| 5746 | //{ | 5856 | //{ |
| ... | @@ -6615,38 +6725,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { | ... | @@ -6615,38 +6725,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { |
| 6615 | // buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name))); | 6725 | // buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name))); |
| 6616 | // return g->builtin_types.entry_invalid; | 6726 | // return g->builtin_types.entry_invalid; |
| 6617 | // } | 6727 | // } |
| 6618 | // } else if (struct_type->id == TypeTableEntryIdNamespace) { | | |
| 6619 | // ConstExprValue *const_val = &get_resolved_expr(*struct_expr_node)->const_val; | | |
| 6620 | // assert(const_val->ok); | | |
| 6621 | // ImportTableEntry *namespace_import = const_val->data.x_import; | | |
| 6622 | // AstNode *decl_node = find_decl(namespace_import->block_context, field_name); | | |
| 6623 | // if (!decl_node) { | | |
| 6624 | // // we must now resolve all the use decls | | |
| 6625 | // for (size_t i = 0; i < namespace_import->use_decls.length; i += 1) { | | |
| 6626 | // AstNode *use_decl_node = namespace_import->use_decls.at(i); | | |
| 6627 | // if (!get_resolved_expr(use_decl_node->data.use.expr)->type_entry) { | | |
| 6628 | // preview_use_decl(g, use_decl_node); | | |
| 6629 | // } | | |
| 6630 | // resolve_use_decl(g, use_decl_node); | | |
| 6631 | // } | | |
| 6632 | // decl_node = find_decl(namespace_import->block_context, field_name); | | |
| 6633 | // } | | |
| 6634 | // if (decl_node) { | | |
| 6635 | // TopLevelDecl *tld = get_as_top_level_decl(decl_node); | | |
| 6636 | // if (tld->visib_mod == VisibModPrivate && decl_node->owner != import) { | | |
| 6637 | // ErrorMsg *msg = add_node_error(g, node, | | |
| 6638 | // buf_sprintf("'%s' is private", buf_ptr(field_name))); | | |
| 6639 | // add_error_note(g, msg, decl_node, buf_sprintf("declared here")); | | |
| 6640 | // } | | |
| 6641 | // bool pointer_only = false; | | |
| 6642 | // return analyze_decl_ref(g, node, decl_node, pointer_only, context, | | |
| 6643 | // const_val->depends_on_compile_var); | | |
| 6644 | // } else { | | |
| 6645 | // const char *import_name = namespace_import->path ? buf_ptr(namespace_import->path) : "(C import)"; | | |
| 6646 | // add_node_error(g, node, | | |
| 6647 | // buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), import_name)); | | |
| 6648 | // return g->builtin_types.entry_invalid; | | |
| 6649 | // } | | |
| 6650 | // } else { | 6728 | // } else { |
| 6651 | // add_node_error(g, node, | 6729 | // add_node_error(g, node, |
| 6652 | // buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name))); | 6730 | // buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name))); |
| ... | @@ -6654,490 +6732,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { | ... | @@ -6654,490 +6732,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { |
| 6654 | // } | 6732 | // } |
| 6655 | //} | 6733 | //} |
| 6656 | // | 6734 | // |
| 6657 | | | |
| 6658 | //static TypeTableEntry *analyze_lvalue(CodeGen *g, ImportTableEntry *import, BlockContext *block_context, | | |
| 6659 | // AstNode *lhs_node, LValPurpose purpose, bool is_ptr_const) | | |
| 6660 | //{ | | |
| 6661 | // TypeTableEntry *expected_rhs_type = nullptr; | | |
| 6662 | // lhs_node->block_context = block_context; | | |
| 6663 | // if (lhs_node->type == NodeTypeSymbol) { | | |
| 6664 | // bool pointer_only = purpose == LValPurposeAddressOf; | | |
| 6665 | // expected_rhs_type = analyze_symbol_expr(g, import, block_context, nullptr, lhs_node, pointer_only); | | |
| 6666 | // if (expected_rhs_type->id == TypeTableEntryIdInvalid) { | | |
| 6667 | // return g->builtin_types.entry_invalid; | | |
| 6668 | // } | | |
| 6669 | // if (purpose != LValPurposeAddressOf) { | | |
| 6670 | // Buf *name = lhs_node->data.symbol_expr.symbol; | | |
| 6671 | // VariableTableEntry *var = find_variable(g, block_context, name); | | |
| 6672 | // if (var) { | | |
| 6673 | // if (var->src_is_const) { | | |
| 6674 | // add_node_error(g, lhs_node, buf_sprintf("cannot assign to constant")); | | |
| 6675 | // expected_rhs_type = g->builtin_types.entry_invalid; | | |
| 6676 | // } else { | | |
| 6677 | // expected_rhs_type = var->type; | | |
| 6678 | // get_resolved_expr(lhs_node)->variable = var; | | |
| 6679 | // } | | |
| 6680 | // } else { | | |
| 6681 | // add_node_error(g, lhs_node, | | |
| 6682 | // buf_sprintf("use of undeclared identifier '%s'", buf_ptr(name))); | | |
| 6683 | // expected_rhs_type = g->builtin_types.entry_invalid; | | |
| 6684 | // } | | |
| 6685 | // } | | |
| 6686 | // } else if (lhs_node->type == NodeTypeArrayAccessExpr) { | | |
| 6687 | // expected_rhs_type = analyze_array_access_expr(g, import, block_context, lhs_node, purpose); | | |
| 6688 | // } else if (lhs_node->type == NodeTypeFieldAccessExpr) { | | |
| 6689 | // expected_rhs_type = analyze_field_access_expr(g, import, block_context, nullptr, lhs_node); | | |
| 6690 | // } else if (lhs_node->type == NodeTypePrefixOpExpr && | | |
| 6691 | // lhs_node->data.prefix_op_expr.prefix_op == PrefixOpDereference) | | |
| 6692 | // { | | |
| 6693 | // assert(purpose == LValPurposeAssign); | | |
| 6694 | // AstNode *target_node = lhs_node->data.prefix_op_expr.primary_expr; | | |
| 6695 | // TypeTableEntry *type_entry = analyze_expression(g, import, block_context, nullptr, target_node); | | |
| 6696 | // if (type_entry->id == TypeTableEntryIdInvalid) { | | |
| 6697 | // expected_rhs_type = type_entry; | | |
| 6698 | // } else if (type_entry->id == TypeTableEntryIdPointer) { | | |
| 6699 | // expected_rhs_type = type_entry->data.pointer.child_type; | | |
| 6700 | // } else { | | |
| 6701 | // add_node_error(g, target_node, | | |
| 6702 | // buf_sprintf("indirection requires pointer operand ('%s' invalid)", | | |
| 6703 | // buf_ptr(&type_entry->name))); | | |
| 6704 | // expected_rhs_type = g->builtin_types.entry_invalid; | | |
| 6705 | // } | | |
| 6706 | // } else { | | |
| 6707 | // if (purpose == LValPurposeAssign) { | | |
| 6708 | // add_node_error(g, lhs_node, buf_sprintf("invalid assignment target")); | | |
| 6709 | // expected_rhs_type = g->builtin_types.entry_invalid; | | |
| 6710 | // } else if (purpose == LValPurposeAddressOf) { | | |
| 6711 | // TypeTableEntry *type_entry = analyze_expression(g, import, block_context, nullptr, lhs_node); | | |
| 6712 | // if (type_entry->id == TypeTableEntryIdInvalid) { | | |
| 6713 | // expected_rhs_type = g->builtin_types.entry_invalid; | | |
| 6714 | // } else if (type_entry->id == TypeTableEntryIdMetaType) { | | |
| 6715 | // expected_rhs_type = type_entry; | | |
| 6716 | // } else { | | |
| 6717 | // add_node_error(g, lhs_node, buf_sprintf("invalid addressof target")); | | |
| 6718 | // expected_rhs_type = g->builtin_types.entry_invalid; | | |
| 6719 | // } | | |
| 6720 | // } | | |
| 6721 | // } | | |
| 6722 | // assert(expected_rhs_type); | | |
| 6723 | // return expected_rhs_type; | | |
| 6724 | //} | | |
| 6725 | | | |
| 6726 | | | |
| 6727 | | | |
| 6728 | //static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | | |
| 6729 | // TypeTableEntry *expected_type, AstNode *node) | | |
| 6730 | //{ | | |
| 6731 | // assert(node->type == NodeTypeBinOpExpr); | | |
| 6732 | // BinOpType bin_op_type = node->data.bin_op_expr.bin_op; | | |
| 6733 | // switch (bin_op_type) { | | |
| 6734 | // case BinOpTypeAssign: | | |
| 6735 | // case BinOpTypeAssignTimes: | | |
| 6736 | // case BinOpTypeAssignTimesWrap: | | |
| 6737 | // case BinOpTypeAssignDiv: | | |
| 6738 | // case BinOpTypeAssignMod: | | |
| 6739 | // case BinOpTypeAssignPlus: | | |
| 6740 | // case BinOpTypeAssignPlusWrap: | | |
| 6741 | // case BinOpTypeAssignMinus: | | |
| 6742 | // case BinOpTypeAssignMinusWrap: | | |
| 6743 | // case BinOpTypeAssignBitShiftLeft: | | |
| 6744 | // case BinOpTypeAssignBitShiftLeftWrap: | | |
| 6745 | // case BinOpTypeAssignBitShiftRight: | | |
| 6746 | // case BinOpTypeAssignBitAnd: | | |
| 6747 | // case BinOpTypeAssignBitXor: | | |
| 6748 | // case BinOpTypeAssignBitOr: | | |
| 6749 | // case BinOpTypeAssignBoolAnd: | | |
| 6750 | // case BinOpTypeAssignBoolOr: | | |
| 6751 | // { | | |
| 6752 | // AstNode *lhs_node = node->data.bin_op_expr.op1; | | |
| 6753 | // | | |
| 6754 | // TypeTableEntry *expected_rhs_type = analyze_lvalue(g, import, context, lhs_node, | | |
| 6755 | // LValPurposeAssign, false); | | |
| 6756 | // if (expected_rhs_type->id == TypeTableEntryIdInvalid) { | | |
| 6757 | // return g->builtin_types.entry_invalid; | | |
| 6758 | // } else if (!is_op_allowed(expected_rhs_type, node->data.bin_op_expr.bin_op)) { | | |
| 6759 | // if (expected_rhs_type->id != TypeTableEntryIdInvalid) { | | |
| 6760 | // add_node_error(g, lhs_node, | | |
| 6761 | // buf_sprintf("operator not allowed for type '%s'", | | |
| 6762 | // buf_ptr(&expected_rhs_type->name))); | | |
| 6763 | // } | | |
| 6764 | // } | | |
| 6765 | // | | |
| 6766 | // analyze_expression(g, import, context, expected_rhs_type, node->data.bin_op_expr.op2); | | |
| 6767 | // // not const ok because expression has side effects | | |
| 6768 | // return g->builtin_types.entry_void; | | |
| 6769 | // } | | |
| 6770 | // case BinOpTypeBoolOr: | | |
| 6771 | // case BinOpTypeBoolAnd: | | |
| 6772 | // return analyze_logic_bin_op_expr(g, import, context, node); | | |
| 6773 | // case BinOpTypeCmpEq: | | |
| 6774 | // case BinOpTypeCmpNotEq: | | |
| 6775 | // case BinOpTypeCmpLessThan: | | |
| 6776 | // case BinOpTypeCmpGreaterThan: | | |
| 6777 | // case BinOpTypeCmpLessOrEq: | | |
| 6778 | // case BinOpTypeCmpGreaterOrEq: | | |
| 6779 | // return analyze_bool_bin_op_expr(g, import, context, node); | | |
| 6780 | // case BinOpTypeBinOr: | | |
| 6781 | // case BinOpTypeBinXor: | | |
| 6782 | // case BinOpTypeBinAnd: | | |
| 6783 | // case BinOpTypeBitShiftLeft: | | |
| 6784 | // case BinOpTypeBitShiftLeftWrap: | | |
| 6785 | // case BinOpTypeBitShiftRight: | | |
| 6786 | // case BinOpTypeAdd: | | |
| 6787 | // case BinOpTypeAddWrap: | | |
| 6788 | // case BinOpTypeSub: | | |
| 6789 | // case BinOpTypeSubWrap: | | |
| 6790 | // case BinOpTypeMult: | | |
| 6791 | // case BinOpTypeMultWrap: | | |
| 6792 | // case BinOpTypeDiv: | | |
| 6793 | // case BinOpTypeMod: | | |
| 6794 | // { | | |
| 6795 | // AstNode **op1 = node->data.bin_op_expr.op1->parent_field; | | |
| 6796 | // AstNode **op2 = node->data.bin_op_expr.op2->parent_field; | | |
| 6797 | // TypeTableEntry *lhs_type = analyze_expression(g, import, context, nullptr, *op1); | | |
| 6798 | // TypeTableEntry *rhs_type = analyze_expression(g, import, context, nullptr, *op2); | | |
| 6799 | // | | |
| 6800 | // AstNode *op_nodes[] = {*op1, *op2}; | | |
| 6801 | // TypeTableEntry *op_types[] = {lhs_type, rhs_type}; | | |
| 6802 | // | | |
| 6803 | // TypeTableEntry *resolved_type = resolve_peer_type_compatibility(g, import, context, node, | | |
| 6804 | // op_nodes, op_types, 2); | | |
| 6805 | // | | |
| 6806 | // if (resolved_type->id == TypeTableEntryIdInvalid) { | | |
| 6807 | // return resolved_type; | | |
| 6808 | // } | | |
| 6809 | // | | |
| 6810 | // if (resolved_type->id == TypeTableEntryIdInt || | | |
| 6811 | // resolved_type->id == TypeTableEntryIdNumLitInt) | | |
| 6812 | // { | | |
| 6813 | // // int | | |
| 6814 | // } else if ((resolved_type->id == TypeTableEntryIdFloat || | | |
| 6815 | // resolved_type->id == TypeTableEntryIdNumLitFloat) && | | |
| 6816 | // (bin_op_type == BinOpTypeAdd || | | |
| 6817 | // bin_op_type == BinOpTypeSub || | | |
| 6818 | // bin_op_type == BinOpTypeMult || | | |
| 6819 | // bin_op_type == BinOpTypeDiv || | | |
| 6820 | // bin_op_type == BinOpTypeMod)) | | |
| 6821 | // { | | |
| 6822 | // // float | | |
| 6823 | // } else { | | |
| 6824 | // add_node_error(g, node, buf_sprintf("invalid operands to binary expression: '%s' and '%s'", | | |
| 6825 | // buf_ptr(&lhs_type->name), buf_ptr(&rhs_type->name))); | | |
| 6826 | // return g->builtin_types.entry_invalid; | | |
| 6827 | // } | | |
| 6828 | // | | |
| 6829 | // ConstExprValue *op1_val = &get_resolved_expr(*op1)->const_val; | | |
| 6830 | // ConstExprValue *op2_val = &get_resolved_expr(*op2)->const_val; | | |
| 6831 | // if (!op1_val->ok || !op2_val->ok) { | | |
| 6832 | // return resolved_type; | | |
| 6833 | // } | | |
| 6834 | // | | |
| 6835 | // ConstExprValue *out_val = &get_resolved_expr(node)->const_val; | | |
| 6836 | // int err; | | |
| 6837 | // if ((err = eval_const_expr_bin_op(op1_val, resolved_type, bin_op_type, | | |
| 6838 | // op2_val, resolved_type, out_val))) | | |
| 6839 | // { | | |
| 6840 | // if (err == ErrorDivByZero) { | | |
| 6841 | // add_node_error(g, node, buf_sprintf("division by zero is undefined")); | | |
| 6842 | // return g->builtin_types.entry_invalid; | | |
| 6843 | // } else if (err == ErrorOverflow) { | | |
| 6844 | // add_node_error(g, node, buf_sprintf("value cannot be represented in any integer type")); | | |
| 6845 | // return g->builtin_types.entry_invalid; | | |
| 6846 | // } | | |
| 6847 | // return g->builtin_types.entry_invalid; | | |
| 6848 | // } | | |
| 6849 | // | | |
| 6850 | // num_lit_fits_in_other_type(g, node, resolved_type); | | |
| 6851 | // return resolved_type; | | |
| 6852 | // } | | |
| 6853 | // case BinOpTypeUnwrapMaybe: | | |
| 6854 | // { | | |
| 6855 | // AstNode *op1 = node->data.bin_op_expr.op1; | | |
| 6856 | // AstNode *op2 = node->data.bin_op_expr.op2; | | |
| 6857 | // TypeTableEntry *lhs_type = analyze_expression(g, import, context, nullptr, op1); | | |
| 6858 | // | | |
| 6859 | // if (lhs_type->id == TypeTableEntryIdInvalid) { | | |
| 6860 | // return lhs_type; | | |
| 6861 | // } else if (lhs_type->id == TypeTableEntryIdMaybe) { | | |
| 6862 | // TypeTableEntry *child_type = lhs_type->data.maybe.child_type; | | |
| 6863 | // analyze_expression(g, import, context, child_type, op2); | | |
| 6864 | // return child_type; | | |
| 6865 | // } else { | | |
| 6866 | // add_node_error(g, op1, | | |
| 6867 | // buf_sprintf("expected maybe type, found '%s'", | | |
| 6868 | // buf_ptr(&lhs_type->name))); | | |
| 6869 | // return g->builtin_types.entry_invalid; | | |
| 6870 | // } | | |
| 6871 | // } | | |
| 6872 | // case BinOpTypeArrayCat: | | |
| 6873 | // { | | |
| 6874 | // AstNode **op1 = node->data.bin_op_expr.op1->parent_field; | | |
| 6875 | // AstNode **op2 = node->data.bin_op_expr.op2->parent_field; | | |
| 6876 | // | | |
| 6877 | // TypeTableEntry *op1_type = analyze_expression(g, import, context, nullptr, *op1); | | |
| 6878 | // TypeTableEntry *child_type; | | |
| 6879 | // if (op1_type->id == TypeTableEntryIdInvalid) { | | |
| 6880 | // return g->builtin_types.entry_invalid; | | |
| 6881 | // } else if (op1_type->id == TypeTableEntryIdArray) { | | |
| 6882 | // child_type = op1_type->data.array.child_type; | | |
| 6883 | // } else if (op1_type->id == TypeTableEntryIdPointer && | | |
| 6884 | // op1_type->data.pointer.child_type == g->builtin_types.entry_u8) { | | |
| 6885 | // child_type = op1_type->data.pointer.child_type; | | |
| 6886 | // } else { | | |
| 6887 | // add_node_error(g, *op1, buf_sprintf("expected array or C string literal, found '%s'", | | |
| 6888 | // buf_ptr(&op1_type->name))); | | |
| 6889 | // return g->builtin_types.entry_invalid; | | |
| 6890 | // } | | |
| 6891 | // | | |
| 6892 | // TypeTableEntry *op2_type = analyze_expression(g, import, context, nullptr, *op2); | | |
| 6893 | // | | |
| 6894 | // if (op2_type->id == TypeTableEntryIdInvalid) { | | |
| 6895 | // return g->builtin_types.entry_invalid; | | |
| 6896 | // } else if (op2_type->id == TypeTableEntryIdArray) { | | |
| 6897 | // if (op2_type->data.array.child_type != child_type) { | | |
| 6898 | // add_node_error(g, *op2, buf_sprintf("expected array of type '%s', found '%s'", | | |
| 6899 | // buf_ptr(&child_type->name), | | |
| 6900 | // buf_ptr(&op2_type->name))); | | |
| 6901 | // return g->builtin_types.entry_invalid; | | |
| 6902 | // } | | |
| 6903 | // } else if (op2_type->id == TypeTableEntryIdPointer && | | |
| 6904 | // op2_type->data.pointer.child_type == g->builtin_types.entry_u8) { | | |
| 6905 | // } else { | | |
| 6906 | // add_node_error(g, *op2, buf_sprintf("expected array or C string literal, found '%s'", | | |
| 6907 | // buf_ptr(&op2_type->name))); | | |
| 6908 | // return g->builtin_types.entry_invalid; | | |
| 6909 | // } | | |
| 6910 | // | | |
| 6911 | // ConstExprValue *op1_val = &get_resolved_expr(*op1)->const_val; | | |
| 6912 | // ConstExprValue *op2_val = &get_resolved_expr(*op2)->const_val; | | |
| 6913 | // | | |
| 6914 | // AstNode *bad_node; | | |
| 6915 | // if (!op1_val->ok) { | | |
| 6916 | // bad_node = *op1; | | |
| 6917 | // } else if (!op2_val->ok) { | | |
| 6918 | // bad_node = *op2; | | |
| 6919 | // } else { | | |
| 6920 | // bad_node = nullptr; | | |
| 6921 | // } | | |
| 6922 | // if (bad_node) { | | |
| 6923 | // add_node_error(g, bad_node, buf_sprintf("array concatenation requires constant expression")); | | |
| 6924 | // return g->builtin_types.entry_invalid; | | |
| 6925 | // } | | |
| 6926 | // | | |
| 6927 | // ConstExprValue *const_val = &get_resolved_expr(node)->const_val; | | |
| 6928 | // const_val->ok = true; | | |
| 6929 | // const_val->depends_on_compile_var = op1_val->depends_on_compile_var || | | |
| 6930 | // op2_val->depends_on_compile_var; | | |
| 6931 | // | | |
| 6932 | // if (op1_type->id == TypeTableEntryIdArray) { | | |
| 6933 | // uint64_t new_len = op1_type->data.array.len + op2_type->data.array.len; | | |
| 6934 | // const_val->data.x_array.fields = allocate<ConstExprValue*>(new_len); | | |
| 6935 | // uint64_t next_index = 0; | | |
| 6936 | // for (uint64_t i = 0; i < op1_type->data.array.len; i += 1, next_index += 1) { | | |
| 6937 | // const_val->data.x_array.fields[next_index] = op1_val->data.x_array.fields[i]; | | |
| 6938 | // } | | |
| 6939 | // for (uint64_t i = 0; i < op2_type->data.array.len; i += 1, next_index += 1) { | | |
| 6940 | // const_val->data.x_array.fields[next_index] = op2_val->data.x_array.fields[i]; | | |
| 6941 | // } | | |
| 6942 | // return get_array_type(g, child_type, new_len); | | |
| 6943 | // } else if (op1_type->id == TypeTableEntryIdPointer) { | | |
| 6944 | // if (!op1_val->data.x_ptr.is_c_str) { | | |
| 6945 | // add_node_error(g, *op1, | | |
| 6946 | // buf_sprintf("expected array or C string literal, found '%s'", | | |
| 6947 | // buf_ptr(&op1_type->name))); | | |
| 6948 | // return g->builtin_types.entry_invalid; | | |
| 6949 | // } else if (!op2_val->data.x_ptr.is_c_str) { | | |
| 6950 | // add_node_error(g, *op2, | | |
| 6951 | // buf_sprintf("expected array or C string literal, found '%s'", | | |
| 6952 | // buf_ptr(&op2_type->name))); | | |
| 6953 | // return g->builtin_types.entry_invalid; | | |
| 6954 | // } | | |
| 6955 | // const_val->data.x_ptr.is_c_str = true; | | |
| 6956 | // const_val->data.x_ptr.len = op1_val->data.x_ptr.len + op2_val->data.x_ptr.len - 1; | | |
| 6957 | // const_val->data.x_ptr.ptr = allocate<ConstExprValue*>(const_val->data.x_ptr.len); | | |
| 6958 | // uint64_t next_index = 0; | | |
| 6959 | // for (uint64_t i = 0; i < op1_val->data.x_ptr.len - 1; i += 1, next_index += 1) { | | |
| 6960 | // const_val->data.x_ptr.ptr[next_index] = op1_val->data.x_ptr.ptr[i]; | | |
| 6961 | // } | | |
| 6962 | // for (uint64_t i = 0; i < op2_val->data.x_ptr.len; i += 1, next_index += 1) { | | |
| 6963 | // const_val->data.x_ptr.ptr[next_index] = op2_val->data.x_ptr.ptr[i]; | | |
| 6964 | // } | | |
| 6965 | // return op1_type; | | |
| 6966 | // } else { | | |
| 6967 | // zig_unreachable(); | | |
| 6968 | // } | | |
| 6969 | // } | | |
| 6970 | // case BinOpTypeArrayMult: | | |
| 6971 | // return analyze_array_mult(g, import, context, expected_type, node); | | |
| 6972 | // case BinOpTypeInvalid: | | |
| 6973 | // zig_unreachable(); | | |
| 6974 | // } | | |
| 6975 | // zig_unreachable(); | | |
| 6976 | //} | | |
| 6977 | | | |
| 6978 | | | |
| 6979 | //static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | | |
| 6980 | // AstNode *node) | | |
| 6981 | //{ | | |
| 6982 | // assert(node->type == NodeTypeBinOpExpr); | | |
| 6983 | // BinOpType bin_op_type = node->data.bin_op_expr.bin_op; | | |
| 6984 | // | | |
| 6985 | // AstNode **op1 = &node->data.bin_op_expr.op1; | | |
| 6986 | // AstNode **op2 = &node->data.bin_op_expr.op2; | | |
| 6987 | // TypeTableEntry *op1_type = analyze_expression(g, import, context, nullptr, *op1); | | |
| 6988 | // TypeTableEntry *op2_type = analyze_expression(g, import, context, nullptr, *op2); | | |
| 6989 | // | | |
| 6990 | // AstNode *op_nodes[] = {*op1, *op2}; | | |
| 6991 | // TypeTableEntry *op_types[] = {op1_type, op2_type}; | | |
| 6992 | // | | |
| 6993 | // TypeTableEntry *resolved_type = resolve_peer_type_compatibility(g, import, context, node, | | |
| 6994 | // op_nodes, op_types, 2); | | |
| 6995 | // | | |
| 6996 | // bool is_equality_cmp = (bin_op_type == BinOpTypeCmpEq || bin_op_type == BinOpTypeCmpNotEq); | | |
| 6997 | // | | |
| 6998 | // switch (resolved_type->id) { | | |
| 6999 | // case TypeTableEntryIdInvalid: | | |
| 7000 | // return g->builtin_types.entry_invalid; | | |
| 7001 | // | | |
| 7002 | // case TypeTableEntryIdNumLitFloat: | | |
| 7003 | // case TypeTableEntryIdNumLitInt: | | |
| 7004 | // case TypeTableEntryIdInt: | | |
| 7005 | // case TypeTableEntryIdFloat: | | |
| 7006 | // break; | | |
| 7007 | // | | |
| 7008 | // case TypeTableEntryIdBool: | | |
| 7009 | // case TypeTableEntryIdMetaType: | | |
| 7010 | // case TypeTableEntryIdVoid: | | |
| 7011 | // case TypeTableEntryIdPointer: | | |
| 7012 | // case TypeTableEntryIdPureError: | | |
| 7013 | // case TypeTableEntryIdFn: | | |
| 7014 | // case TypeTableEntryIdTypeDecl: | | |
| 7015 | // case TypeTableEntryIdNamespace: | | |
| 7016 | // case TypeTableEntryIdBlock: | | |
| 7017 | // case TypeTableEntryIdGenericFn: | | |
| 7018 | // if (!is_equality_cmp) { | | |
| 7019 | // add_node_error(g, node, | | |
| 7020 | // buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name))); | | |
| 7021 | // return g->builtin_types.entry_invalid; | | |
| 7022 | // } | | |
| 7023 | // break; | | |
| 7024 | // | | |
| 7025 | // case TypeTableEntryIdEnum: | | |
| 7026 | // if (!is_equality_cmp || resolved_type->data.enumeration.gen_field_count != 0) { | | |
| 7027 | // add_node_error(g, node, | | |
| 7028 | // buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name))); | | |
| 7029 | // return g->builtin_types.entry_invalid; | | |
| 7030 | // } | | |
| 7031 | // break; | | |
| 7032 | // | | |
| 7033 | // case TypeTableEntryIdUnreachable: | | |
| 7034 | // case TypeTableEntryIdArray: | | |
| 7035 | // case TypeTableEntryIdStruct: | | |
| 7036 | // case TypeTableEntryIdUndefLit: | | |
| 7037 | // case TypeTableEntryIdNullLit: | | |
| 7038 | // case TypeTableEntryIdMaybe: | | |
| 7039 | // case TypeTableEntryIdErrorUnion: | | |
| 7040 | // case TypeTableEntryIdUnion: | | |
| 7041 | // add_node_error(g, node, | | |
| 7042 | // buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name))); | | |
| 7043 | // return g->builtin_types.entry_invalid; | | |
| 7044 | // | | |
| 7045 | // case TypeTableEntryIdVar: | | |
| 7046 | // zig_unreachable(); | | |
| 7047 | // } | | |
| 7048 | // | | |
| 7049 | // ConstExprValue *op1_val = &get_resolved_expr(*op1)->const_val; | | |
| 7050 | // ConstExprValue *op2_val = &get_resolved_expr(*op2)->const_val; | | |
| 7051 | // if (!op1_val->ok || !op2_val->ok) { | | |
| 7052 | // return g->builtin_types.entry_bool; | | |
| 7053 | // } | | |
| 7054 | // | | |
| 7055 | // | | |
| 7056 | // ConstExprValue *out_val = &get_resolved_expr(node)->const_val; | | |
| 7057 | // eval_const_expr_bin_op(op1_val, op1_type, bin_op_type, op2_val, op2_type, out_val); | | |
| 7058 | // return g->builtin_types.entry_bool; | | |
| 7059 | // | | |
| 7060 | //} | | |
| 7061 | // | | |
| 7062 | //// | | |
| 7063 | //static TypeTableEntry *analyze_if(CodeGen *g, ImportTableEntry *import, BlockContext *parent_context, | | |
| 7064 | // TypeTableEntry *expected_type, AstNode *node, | | |
| 7065 | // AstNode **then_node, AstNode **else_node, bool cond_is_const, bool cond_bool_val) | | |
| 7066 | //{ | | |
| 7067 | // if (!*else_node) { | | |
| 7068 | // *else_node = create_ast_void_node(g, import, node); | | |
| 7069 | // normalize_parent_ptrs(node); | | |
| 7070 | // } | | |
| 7071 | // | | |
| 7072 | // BlockContext *then_context; | | |
| 7073 | // BlockContext *else_context; | | |
| 7074 | // if (cond_is_const) { | | |
| 7075 | // if (cond_bool_val) { | | |
| 7076 | // then_context = parent_context; | | |
| 7077 | // else_context = new_block_context(node, parent_context); | | |
| 7078 | // | | |
| 7079 | // else_context->codegen_excluded = true; | | |
| 7080 | // } else { | | |
| 7081 | // then_context = new_block_context(node, parent_context); | | |
| 7082 | // else_context = parent_context; | | |
| 7083 | // | | |
| 7084 | // then_context->codegen_excluded = true; | | |
| 7085 | // } | | |
| 7086 | // } else { | | |
| 7087 | // then_context = parent_context; | | |
| 7088 | // else_context = parent_context; | | |
| 7089 | // } | | |
| 7090 | // | | |
| 7091 | // TypeTableEntry *then_type = nullptr; | | |
| 7092 | // TypeTableEntry *else_type = nullptr; | | |
| 7093 | // | | |
| 7094 | // if (!then_context->codegen_excluded) { | | |
| 7095 | // then_type = analyze_expression(g, import, then_context, expected_type, *then_node); | | |
| 7096 | // if (then_type->id == TypeTableEntryIdInvalid) { | | |
| 7097 | // return g->builtin_types.entry_invalid; | | |
| 7098 | // } | | |
| 7099 | // } | | |
| 7100 | // if (!else_context->codegen_excluded) { | | |
| 7101 | // else_type = analyze_expression(g, import, else_context, expected_type, *else_node); | | |
| 7102 | // if (else_type->id == TypeTableEntryIdInvalid) { | | |
| 7103 | // return g->builtin_types.entry_invalid; | | |
| 7104 | // } | | |
| 7105 | // } | | |
| 7106 | // | | |
| 7107 | // TypeTableEntry *result_type; | | |
| 7108 | // if (then_context->codegen_excluded) { | | |
| 7109 | // result_type = else_type; | | |
| 7110 | // } else if (else_context->codegen_excluded) { | | |
| 7111 | // result_type = then_type; | | |
| 7112 | // } else if (expected_type) { | | |
| 7113 | // result_type = (then_type->id == TypeTableEntryIdUnreachable) ? else_type : then_type; | | |
| 7114 | // } else { | | |
| 7115 | // AstNode *op_nodes[] = {*then_node, *else_node}; | | |
| 7116 | // TypeTableEntry *op_types[] = {then_type, else_type}; | | |
| 7117 | // result_type = resolve_peer_type_compatibility(g, import, parent_context, node, op_nodes, op_types, 2); | | |
| 7118 | // } | | |
| 7119 | // | | |
| 7120 | // if (!cond_is_const) { | | |
| 7121 | // return add_error_if_type_is_num_lit(g, result_type, node); | | |
| 7122 | // } | | |
| 7123 | // | | |
| 7124 | // ConstExprValue *other_const_val; | | |
| 7125 | // if (cond_bool_val) { | | |
| 7126 | // other_const_val = &get_resolved_expr(*then_node)->const_val; | | |
| 7127 | // } else { | | |
| 7128 | // other_const_val = &get_resolved_expr(*else_node)->const_val; | | |
| 7129 | // } | | |
| 7130 | // if (!other_const_val->ok) { | | |
| 7131 | // return add_error_if_type_is_num_lit(g, result_type, node); | | |
| 7132 | // } | | |
| 7133 | // | | |
| 7134 | // ConstExprValue *const_val = &get_resolved_expr(node)->const_val; | | |
| 7135 | // *const_val = *other_const_val; | | |
| 7136 | // // the condition depends on a compile var, so the entire if statement does too | | |
| 7137 | // const_val->depends_on_compile_var = true; | | |
| 7138 | // return result_type; | | |
| 7139 | //} | | |
| 7140 | // | | |
| 7141 | //static TypeTableEntry *bad_method_call(CodeGen *g, AstNode *node, TypeTableEntry *container_type, | 6735 | //static TypeTableEntry *bad_method_call(CodeGen *g, AstNode *node, TypeTableEntry *container_type, |
| 7142 | // TypeTableEntry *expected_param_type, FnTableEntry *fn_table_entry) | 6736 | // TypeTableEntry *expected_param_type, FnTableEntry *fn_table_entry) |
| 7143 | //{ | 6737 | //{ |
| ... | @@ -8195,92 +7789,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { | ... | @@ -8195,92 +7789,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { |
| 8195 | // return g->builtin_types.entry_invalid; | 7789 | // return g->builtin_types.entry_invalid; |
| 8196 | //} | 7790 | //} |
| 8197 | // | 7791 | // |
| 8198 | //static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | | |
| 8199 | // TypeTableEntry *expected_type, AstNode *node, bool pointer_only) | | |
| 8200 | //{ | | |
| 8201 | // Buf *variable_name = node->data.symbol_expr.symbol; | | |
| 8202 | // | | |
| 8203 | // auto primitive_table_entry = g->primitive_type_table.maybe_get(variable_name); | | |
| 8204 | // if (primitive_table_entry) { | | |
| 8205 | // return resolve_expr_const_val_as_type(g, node, primitive_table_entry->value, false); | | |
| 8206 | // } | | |
| 8207 | // | | |
| 8208 | // VariableTableEntry *var = find_variable(g, context, variable_name); | | |
| 8209 | // if (var) { | | |
| 8210 | // TypeTableEntry *var_type = analyze_var_ref(g, node, var, context, false); | | |
| 8211 | // return var_type; | | |
| 8212 | // } | | |
| 8213 | // | | |
| 8214 | // AstNode *decl_node = find_decl(context, variable_name); | | |
| 8215 | // if (decl_node) { | | |
| 8216 | // return analyze_decl_ref(g, node, decl_node, pointer_only, context, false); | | |
| 8217 | // } | | |
| 8218 | // | | |
| 8219 | // if (import->any_imports_failed) { | | |
| 8220 | // // skip the error message since we had a failing import in this file | | |
| 8221 | // // if an import breaks we don't need 9999 undeclared identifier errors | | |
| 8222 | // return g->builtin_types.entry_invalid; | | |
| 8223 | // } | | |
| 8224 | // | | |
| 8225 | // mark_impure_fn(g, context, node); | | |
| 8226 | // add_node_error(g, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); | | |
| 8227 | // return g->builtin_types.entry_invalid; | | |
| 8228 | //} | | |
| 8229 | // | | |
| 8230 | //static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNode *decl_node, | | |
| 8231 | // bool pointer_only, BlockContext *block_context, bool depends_on_compile_var) | | |
| 8232 | //{ | | |
| 8233 | // resolve_top_level_decl(g, decl_node, pointer_only); | | |
| 8234 | // TopLevelDecl *tld = get_as_top_level_decl(decl_node); | | |
| 8235 | // if (tld->resolution == TldResolutionInvalid) { | | |
| 8236 | // return g->builtin_types.entry_invalid; | | |
| 8237 | // } | | |
| 8238 | // | | |
| 8239 | // if (decl_node->type == NodeTypeVariableDeclaration) { | | |
| 8240 | // VariableTableEntry *var = decl_node->data.variable_declaration.variable; | | |
| 8241 | // return analyze_var_ref(g, source_node, var, block_context, depends_on_compile_var); | | |
| 8242 | // } else if (decl_node->type == NodeTypeFnProto) { | | |
| 8243 | // FnTableEntry *fn_entry = decl_node->data.fn_proto.fn_table_entry; | | |
| 8244 | // assert(fn_entry->type_entry); | | |
| 8245 | // if (fn_entry->type_entry->id == TypeTableEntryIdGenericFn) { | | |
| 8246 | // return resolve_expr_const_val_as_generic_fn(g, source_node, fn_entry->type_entry, depends_on_compile_var); | | |
| 8247 | // } else { | | |
| 8248 | // return resolve_expr_const_val_as_fn(g, source_node, fn_entry, depends_on_compile_var); | | |
| 8249 | // } | | |
| 8250 | // } else if (decl_node->type == NodeTypeContainerDecl) { | | |
| 8251 | // if (decl_node->data.struct_decl.generic_params.length > 0) { | | |
| 8252 | // TypeTableEntry *type_entry = decl_node->data.struct_decl.generic_fn_type; | | |
| 8253 | // assert(type_entry); | | |
| 8254 | // return resolve_expr_const_val_as_generic_fn(g, source_node, type_entry, depends_on_compile_var); | | |
| 8255 | // } else { | | |
| 8256 | // return resolve_expr_const_val_as_type(g, source_node, decl_node->data.struct_decl.type_entry, | | |
| 8257 | // depends_on_compile_var); | | |
| 8258 | // } | | |
| 8259 | // } else if (decl_node->type == NodeTypeTypeDecl) { | | |
| 8260 | // return resolve_expr_const_val_as_type(g, source_node, decl_node->data.type_decl.child_type_entry, | | |
| 8261 | // depends_on_compile_var); | | |
| 8262 | // } else { | | |
| 8263 | // zig_unreachable(); | | |
| 8264 | // } | | |
| 8265 | //} | | |
| 8266 | // | | |
| 8267 | //static TypeTableEntry *analyze_var_ref(CodeGen *g, AstNode *source_node, VariableTableEntry *var, | | |
| 8268 | // BlockContext *context, bool depends_on_compile_var) | | |
| 8269 | //{ | | |
| 8270 | // get_resolved_expr(source_node)->variable = var; | | |
| 8271 | // if (!var_is_pure(var, context)) { | | |
| 8272 | // mark_impure_fn(g, context, source_node); | | |
| 8273 | // } | | |
| 8274 | // if (var->src_is_const && var->val_node) { | | |
| 8275 | // ConstExprValue *other_const_val = &get_resolved_expr(var->val_node)->const_val; | | |
| 8276 | // if (other_const_val->ok) { | | |
| 8277 | // return resolve_expr_const_val_as_other_expr(g, source_node, var->val_node, | | |
| 8278 | // depends_on_compile_var || var->force_depends_on_compile_var); | | |
| 8279 | // } | | |
| 8280 | // } | | |
| 8281 | // return var->type; | | |
| 8282 | //} | | |
| 8283 | // | | |
| 8284 | //static TypeTableEntry *analyze_fn_proto_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 7792 | //static TypeTableEntry *analyze_fn_proto_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 8285 | // TypeTableEntry *expected_type, AstNode *node) | 7793 | // TypeTableEntry *expected_type, AstNode *node) |
| 8286 | //{ | 7794 | //{ |
| ... | @@ -8294,14 +7802,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { | ... | @@ -8294,14 +7802,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { |
| 8294 | // return resolve_expr_const_val_as_type(g, node, type_entry, false); | 7802 | // return resolve_expr_const_val_as_type(g, node, type_entry, false); |
| 8295 | //} | 7803 | //} |
| 8296 | // | 7804 | // |
| 8297 | //static bool var_is_pure(VariableTableEntry *var, BlockContext *context) { | | |
| 8298 | // if (var->block_context->fn_entry == context->fn_entry) { | | |
| 8299 | // // variable was declared in the current function, so it's OK. | | |
| 8300 | // return true; | | |
| 8301 | // } | | |
| 8302 | // return var->src_is_const && var->type->deep_const; | | |
| 8303 | //} | | |
| 8304 | // | | |
| 8305 | //static void validate_voided_expr(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry) { | 7805 | //static void validate_voided_expr(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry) { |
| 8306 | // if (type_entry->id == TypeTableEntryIdMetaType) { | 7806 | // if (type_entry->id == TypeTableEntryIdMetaType) { |
| 8307 | // add_node_error(g, first_executing_node(source_node), buf_sprintf("expected expression, found type")); | 7807 | // add_node_error(g, first_executing_node(source_node), buf_sprintf("expected expression, found type")); |
| ... | @@ -8949,54 +8449,6 @@ static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *no | ... | @@ -8949,54 +8449,6 @@ static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *no |
| 8949 | //} | 8449 | //} |
| 8950 | // | 8450 | // |
| 8951 | // | 8451 | // |
| 8952 | //static LLVMValueRef gen_lvalue(CodeGen *g, AstNode *expr_node, AstNode *node, | | |
| 8953 | // TypeTableEntry **out_type_entry) | | |
| 8954 | //{ | | |
| 8955 | // LLVMValueRef target_ref; | | |
| 8956 | // | | |
| 8957 | // if (node->type == NodeTypeSymbol) { | | |
| 8958 | // VariableTableEntry *var = get_resolved_expr(node)->variable; | | |
| 8959 | // assert(var); | | |
| 8960 | // | | |
| 8961 | // *out_type_entry = var->type; | | |
| 8962 | // target_ref = var->value_ref; | | |
| 8963 | // } else if (node->type == NodeTypeArrayAccessExpr) { | | |
| 8964 | // TypeTableEntry *array_type = get_expr_type(node->data.array_access_expr.array_ref_expr); | | |
| 8965 | // if (array_type->id == TypeTableEntryIdArray) { | | |
| 8966 | // *out_type_entry = array_type->data.array.child_type; | | |
| 8967 | // target_ref = gen_array_ptr(g, node); | | |
| 8968 | // } else if (array_type->id == TypeTableEntryIdPointer) { | | |
| 8969 | // *out_type_entry = array_type->data.pointer.child_type; | | |
| 8970 | // target_ref = gen_array_ptr(g, node); | | |
| 8971 | // } else if (array_type->id == TypeTableEntryIdStruct) { | | |
| 8972 | // assert(array_type->data.structure.is_slice); | | |
| 8973 | // *out_type_entry = array_type->data.structure.fields[0].type_entry->data.pointer.child_type; | | |
| 8974 | // target_ref = gen_array_ptr(g, node); | | |
| 8975 | // } else { | | |
| 8976 | // zig_unreachable(); | | |
| 8977 | // } | | |
| 8978 | // } else if (node->type == NodeTypeFieldAccessExpr) { | | |
| 8979 | // AstNode *struct_expr_node = node->data.field_access_expr.struct_expr; | | |
| 8980 | // TypeTableEntry *struct_type = get_expr_type(struct_expr_node); | | |
| 8981 | // if (struct_type->id == TypeTableEntryIdNamespace) { | | |
| 8982 | // target_ref = gen_field_access_expr(g, node, true); | | |
| 8983 | // *out_type_entry = get_expr_type(node); | | |
| 8984 | // } else { | | |
| 8985 | // target_ref = gen_field_ptr(g, node, out_type_entry); | | |
| 8986 | // } | | |
| 8987 | // } else if (node->type == NodeTypePrefixOpExpr) { | | |
| 8988 | // assert(node->data.prefix_op_expr.prefix_op == PrefixOpDereference); | | |
| 8989 | // AstNode *target_expr = node->data.prefix_op_expr.primary_expr; | | |
| 8990 | // TypeTableEntry *type_entry = get_expr_type(target_expr); | | |
| 8991 | // assert(type_entry->id == TypeTableEntryIdPointer); | | |
| 8992 | // *out_type_entry = type_entry->data.pointer.child_type; | | |
| 8993 | // return gen_expr(g, target_expr); | | |
| 8994 | // } else { | | |
| 8995 | // zig_panic("bad assign target"); | | |
| 8996 | // } | | |
| 8997 | // | | |
| 8998 | // return target_ref; | | |
| 8999 | //} | | |
| 9000 | // | 8452 | // |
| 9001 | //static LLVMValueRef gen_bool_and_expr(CodeGen *g, AstNode *node) { | 8453 | //static LLVMValueRef gen_bool_and_expr(CodeGen *g, AstNode *node) { |
| 9002 | // assert(node->type == NodeTypeBinOpExpr); | 8454 | // assert(node->type == NodeTypeBinOpExpr); |