@@ -567,6 +567,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSetAlignStack *)
567
567
return IrInstructionIdSetAlignStack;
568
568
}
569
569
570
+ static constexpr IrInstructionId ir_instruction_id(IrInstructionArgType *) {
571
+ return IrInstructionIdArgType;
572
+ }
573
+
570
574
template<typename T>
571
575
static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
572
576
T *special_instruction = allocate<T>(1);
@@ -2263,6 +2267,19 @@ static IrInstruction *ir_build_set_align_stack(IrBuilder *irb, Scope *scope, Ast
2263
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
2283
static IrInstruction *ir_instruction_br_get_dep(IrInstructionBr *instruction, size_t index) {
2267
2284
return nullptr;
2268
2285
}
@@ -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
3020
static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t index) {
2996
3021
switch (instruction->id) {
2997
3022
case IrInstructionIdInvalid:
@@ -3194,6 +3219,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
3194
3219
return ir_instruction_opaquetype_get_dep((IrInstructionOpaqueType *) instruction, index);
3195
3220
case IrInstructionIdSetAlignStack:
3196
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
3225
zig_unreachable();
3199
3226
}
@@ -4629,6 +4656,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4629
4656
4630
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
4674
zig_unreachable();
4634
4675
}
@@ -11686,6 +11727,13 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
11686
11727
create_const_bool(ira->codegen, child_type->data.fn.fn_type_id.is_var_args),
11687
11728
ira->codegen->builtin_types.entry_bool,
11688
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
11737
} else {
11690
11738
ir_add_error(ira, &field_ptr_instruction->base,
11691
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
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
15475
static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
15399
15476
switch (instruction->id) {
15400
15477
case IrInstructionIdInvalid:
@@ -15585,6 +15662,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
15585
15662
return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction);
15586
15663
case IrInstructionIdSetAlignStack:
15587
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
15668
zig_unreachable();
15590
15669
}
@@ -15765,6 +15844,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
15765
15844
case IrInstructionIdTypeId:
15766
15845
case IrInstructionIdAlignCast:
15767
15846
case IrInstructionIdOpaqueType:
15847
+ case IrInstructionIdArgType:
15768
15848
return false;
15769
15849
case IrInstructionIdAsm:
15770
15850
{
0 commit comments