| ... | @@ -567,6 +567,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSetAlignStack *) | ... | @@ -567,6 +567,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSetAlignStack *) |
| 567 | return IrInstructionIdSetAlignStack; | 567 | return IrInstructionIdSetAlignStack; |
| 568 | } | 568 | } |
| 569 | | 569 | |
| | 570 | static constexpr IrInstructionId ir_instruction_id(IrInstructionArgType *) { |
| | 571 | return IrInstructionIdArgType; |
| | 572 | } |
| | 573 | |
| 570 | template<typename T> | 574 | template<typename T> |
| 571 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { | 575 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 572 | T *special_instruction = allocate<T>(1); | 576 | T *special_instruction = allocate<T>(1); |
| ... | @@ -2263,6 +2267,19 @@ static IrInstruction *ir_build_set_align_stack(IrBuilder *irb, Scope *scope, Ast | ... | @@ -2263,6 +2267,19 @@ static IrInstruction *ir_build_set_align_stack(IrBuilder *irb, Scope *scope, Ast |
| 2263 | return &instruction->base; | 2267 | return &instruction->base; |
| 2264 | } | 2268 | } |
| 2265 | | 2269 | |
| | 2270 | static IrInstruction *ir_build_arg_type(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 2271 | IrInstruction *fn_type, IrInstruction *arg_index) |
| | 2272 | { |
| | 2273 | IrInstructionArgType *instruction = ir_build_instruction<IrInstructionArgType>(irb, scope, source_node); |
| | 2274 | instruction->fn_type = fn_type; |
| | 2275 | instruction->arg_index = arg_index; |
| | 2276 | |
| | 2277 | ir_ref_instruction(fn_type, irb->current_basic_block); |
| | 2278 | ir_ref_instruction(arg_index, irb->current_basic_block); |
| | 2279 | |
| | 2280 | return &instruction->base; |
| | 2281 | } |
| | 2282 | |
| 2266 | static IrInstruction *ir_instruction_br_get_dep(IrInstructionBr *instruction, size_t index) { | 2283 | static IrInstruction *ir_instruction_br_get_dep(IrInstructionBr *instruction, size_t index) { |
| 2267 | return nullptr; | 2284 | return nullptr; |
| 2268 | } | 2285 | } |
| ... | @@ -2992,6 +3009,14 @@ static IrInstruction *ir_instruction_setalignstack_get_dep(IrInstructionSetAlign | ... | @@ -2992,6 +3009,14 @@ static IrInstruction *ir_instruction_setalignstack_get_dep(IrInstructionSetAlign |
| 2992 | } | 3009 | } |
| 2993 | } | 3010 | } |
| 2994 | | 3011 | |
| | 3012 | static IrInstruction *ir_instruction_argtype_get_dep(IrInstructionArgType *instruction, size_t index) { |
| | 3013 | switch (index) { |
| | 3014 | case 0: return instruction->fn_type; |
| | 3015 | case 1: return instruction->arg_index; |
| | 3016 | default: return nullptr; |
| | 3017 | } |
| | 3018 | } |
| | 3019 | |
| 2995 | static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t index) { | 3020 | static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t index) { |
| 2996 | switch (instruction->id) { | 3021 | switch (instruction->id) { |
| 2997 | case IrInstructionIdInvalid: | 3022 | case IrInstructionIdInvalid: |
| ... | @@ -3194,6 +3219,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t | ... | @@ -3194,6 +3219,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t |
| 3194 | return ir_instruction_opaquetype_get_dep((IrInstructionOpaqueType *) instruction, index); | 3219 | return ir_instruction_opaquetype_get_dep((IrInstructionOpaqueType *) instruction, index); |
| 3195 | case IrInstructionIdSetAlignStack: | 3220 | case IrInstructionIdSetAlignStack: |
| 3196 | return ir_instruction_setalignstack_get_dep((IrInstructionSetAlignStack *) instruction, index); | 3221 | return ir_instruction_setalignstack_get_dep((IrInstructionSetAlignStack *) instruction, index); |
| | 3222 | case IrInstructionIdArgType: |
| | 3223 | return ir_instruction_argtype_get_dep((IrInstructionArgType *) instruction, index); |
| 3197 | } | 3224 | } |
| 3198 | zig_unreachable(); | 3225 | zig_unreachable(); |
| 3199 | } | 3226 | } |
| ... | @@ -4629,6 +4656,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4629,6 +4656,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4629 | | 4656 | |
| 4630 | return ir_build_set_align_stack(irb, scope, node, arg0_value); | 4657 | return ir_build_set_align_stack(irb, scope, node, arg0_value); |
| 4631 | } | 4658 | } |
| | 4659 | case BuiltinFnIdArgType: |
| | 4660 | { |
| | 4661 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| | 4662 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); |
| | 4663 | if (arg0_value == irb->codegen->invalid_instruction) |
| | 4664 | return arg0_value; |
| | 4665 | |
| | 4666 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); |
| | 4667 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); |
| | 4668 | if (arg1_value == irb->codegen->invalid_instruction) |
| | 4669 | return arg1_value; |
| | 4670 | |
| | 4671 | return ir_build_arg_type(irb, scope, node, arg0_value, arg1_value); |
| | 4672 | } |
| 4632 | } | 4673 | } |
| 4633 | zig_unreachable(); | 4674 | zig_unreachable(); |
| 4634 | } | 4675 | } |
| ... | @@ -11686,6 +11727,13 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru | ... | @@ -11686,6 +11727,13 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 11686 | create_const_bool(ira->codegen, child_type->data.fn.fn_type_id.is_var_args), | 11727 | create_const_bool(ira->codegen, child_type->data.fn.fn_type_id.is_var_args), |
| 11687 | ira->codegen->builtin_types.entry_bool, | 11728 | ira->codegen->builtin_types.entry_bool, |
| 11688 | ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); | 11729 | ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); |
| | 11730 | } else if (buf_eql_str(field_name, "arg_count")) { |
| | 11731 | bool ptr_is_const = true; |
| | 11732 | bool ptr_is_volatile = false; |
| | 11733 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, |
| | 11734 | create_const_usize(ira->codegen, child_type->data.fn.fn_type_id.param_count), |
| | 11735 | ira->codegen->builtin_types.entry_usize, |
| | 11736 | ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); |
| 11689 | } else { | 11737 | } else { |
| 11690 | ir_add_error(ira, &field_ptr_instruction->base, | 11738 | ir_add_error(ira, &field_ptr_instruction->base, |
| 11691 | buf_sprintf("type '%s' has no member called '%s'", | 11739 | buf_sprintf("type '%s' has no member called '%s'", |
| ... | @@ -15395,6 +15443,35 @@ static TypeTableEntry *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, Ir | ... | @@ -15395,6 +15443,35 @@ static TypeTableEntry *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, Ir |
| 15395 | return ira->codegen->builtin_types.entry_void; | 15443 | return ira->codegen->builtin_types.entry_void; |
| 15396 | } | 15444 | } |
| 15397 | | 15445 | |
| | 15446 | static TypeTableEntry *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstructionArgType *instruction) { |
| | 15447 | IrInstruction *fn_type_inst = instruction->fn_type->other; |
| | 15448 | TypeTableEntry *fn_type = ir_resolve_type(ira, fn_type_inst); |
| | 15449 | if (type_is_invalid(fn_type)) |
| | 15450 | return ira->codegen->builtin_types.entry_invalid; |
| | 15451 | |
| | 15452 | IrInstruction *arg_index_inst = instruction->arg_index->other; |
| | 15453 | uint64_t arg_index; |
| | 15454 | if (!ir_resolve_usize(ira, arg_index_inst, &arg_index)) |
| | 15455 | return ira->codegen->builtin_types.entry_invalid; |
| | 15456 | |
| | 15457 | if (fn_type->id != TypeTableEntryIdFn) { |
| | 15458 | ir_add_error(ira, fn_type_inst, buf_sprintf("expected function, found '%s'", buf_ptr(&fn_type->name))); |
| | 15459 | return ira->codegen->builtin_types.entry_invalid; |
| | 15460 | } |
| | 15461 | |
| | 15462 | FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; |
| | 15463 | if (arg_index >= fn_type_id->param_count) { |
| | 15464 | ir_add_error(ira, arg_index_inst, |
| | 15465 | buf_sprintf("arg index %" ZIG_PRI_usize " out of bounds; '%s' has %" ZIG_PRI_usize " arguments", |
| | 15466 | arg_index, buf_ptr(&fn_type->name), fn_type_id->param_count)); |
| | 15467 | return ira->codegen->builtin_types.entry_invalid; |
| | 15468 | } |
| | 15469 | |
| | 15470 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| | 15471 | out_val->data.x_type = fn_type_id->param_info[arg_index].type; |
| | 15472 | return ira->codegen->builtin_types.entry_type; |
| | 15473 | } |
| | 15474 | |
| 15398 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { | 15475 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { |
| 15399 | switch (instruction->id) { | 15476 | switch (instruction->id) { |
| 15400 | case IrInstructionIdInvalid: | 15477 | case IrInstructionIdInvalid: |
| ... | @@ -15585,6 +15662,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -15585,6 +15662,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 15585 | return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction); | 15662 | return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction); |
| 15586 | case IrInstructionIdSetAlignStack: | 15663 | case IrInstructionIdSetAlignStack: |
| 15587 | return ir_analyze_instruction_set_align_stack(ira, (IrInstructionSetAlignStack *)instruction); | 15664 | return ir_analyze_instruction_set_align_stack(ira, (IrInstructionSetAlignStack *)instruction); |
| | 15665 | case IrInstructionIdArgType: |
| | 15666 | return ir_analyze_instruction_arg_type(ira, (IrInstructionArgType *)instruction); |
| 15588 | } | 15667 | } |
| 15589 | zig_unreachable(); | 15668 | zig_unreachable(); |
| 15590 | } | 15669 | } |
| ... | @@ -15765,6 +15844,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -15765,6 +15844,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 15765 | case IrInstructionIdTypeId: | 15844 | case IrInstructionIdTypeId: |
| 15766 | case IrInstructionIdAlignCast: | 15845 | case IrInstructionIdAlignCast: |
| 15767 | case IrInstructionIdOpaqueType: | 15846 | case IrInstructionIdOpaqueType: |
| | 15847 | case IrInstructionIdArgType: |
| 15768 | return false; | 15848 | return false; |
| 15769 | case IrInstructionIdAsm: | 15849 | case IrInstructionIdAsm: |
| 15770 | { | 15850 | { |