| ... | ... | @@ -851,6 +851,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeInfo *) { |
| 851 | 851 | return IrInstructionIdTypeInfo; |
| 852 | 852 | } |
| 853 | 853 | |
| 854 | static constexpr IrInstructionId ir_instruction_id(IrInstructionHasField *) { |
| 855 | return IrInstructionIdHasField; |
| 856 | } |
| 857 | |
| 854 | 858 | static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeId *) { |
| 855 | 859 | return IrInstructionIdTypeId; |
| 856 | 860 | } |
| ... | ... | @@ -1280,6 +1284,20 @@ static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode * |
| 1280 | 1284 | return &instruction->base; |
| 1281 | 1285 | } |
| 1282 | 1286 | |
| 1287 | static IrInstruction *ir_build_has_field(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1288 | IrInstruction *container_type, IrInstruction *field_name_expr) |
| 1289 | { |
| 1290 | IrInstructionHasField *instruction = ir_build_instruction<IrInstructionHasField>(irb, scope, source_node); |
| 1291 | instruction->container_type = container_type; |
| 1292 | instruction->field_name_buffer = nullptr; |
| 1293 | instruction->field_name_expr = field_name_expr; |
| 1294 | |
| 1295 | ir_ref_instruction(container_type, irb->current_basic_block); |
| 1296 | ir_ref_instruction(field_name_expr, irb->current_basic_block); |
| 1297 | |
| 1298 | return &instruction->base; |
| 1299 | } |
| 1300 | |
| 1283 | 1301 | static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1284 | 1302 | IrInstruction *struct_ptr, TypeStructField *field) |
| 1285 | 1303 | { |
| ... | ... | @@ -4598,6 +4616,21 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4598 | 4616 | |
| 4599 | 4617 | return ir_build_load_ptr(irb, scope, node, ptr_instruction); |
| 4600 | 4618 | } |
| 4619 | case BuiltinFnIdHasField: |
| 4620 | { |
| 4621 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 4622 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); |
| 4623 | if (arg0_value == irb->codegen->invalid_instruction) |
| 4624 | return arg0_value; |
| 4625 | |
| 4626 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); |
| 4627 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); |
| 4628 | if (arg1_value == irb->codegen->invalid_instruction) |
| 4629 | return arg1_value; |
| 4630 | |
| 4631 | IrInstruction *type_info = ir_build_has_field(irb, scope, node, arg0_value, arg1_value); |
| 4632 | return ir_lval_wrap(irb, scope, type_info, lval); |
| 4633 | } |
| 4601 | 4634 | case BuiltinFnIdTypeInfo: |
| 4602 | 4635 | { |
| 4603 | 4636 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | ... | @@ -20578,6 +20611,40 @@ static IrInstruction *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInstr |
| 20578 | 20611 | } |
| 20579 | 20612 | } |
| 20580 | 20613 | |
| 20614 | static IrInstruction *ir_analyze_instruction_has_field(IrAnalyze *ira, IrInstructionHasField *instruction) { |
| 20615 | Error err; |
| 20616 | IrInstruction *container_type_value = instruction->container_type->child; |
| 20617 | ZigType *container_type = ir_resolve_type(ira, container_type_value); |
| 20618 | if (type_is_invalid(container_type)) |
| 20619 | return ira->codegen->invalid_instruction; |
| 20620 | |
| 20621 | if ((err = ensure_complete_type(ira->codegen, container_type))) |
| 20622 | return ira->codegen->invalid_instruction; |
| 20623 | |
| 20624 | Buf *field_name = instruction->field_name_buffer; |
| 20625 | if (!field_name) { |
| 20626 | IrInstruction *field_name_expr = instruction->field_name_expr->child; |
| 20627 | field_name = ir_resolve_str(ira, field_name_expr); |
| 20628 | if (!field_name) |
| 20629 | return ira->codegen->invalid_instruction; |
| 20630 | } |
| 20631 | |
| 20632 | bool result; |
| 20633 | if (container_type->id == ZigTypeIdStruct) |
| 20634 | result = (bool)find_struct_type_field(container_type, field_name); |
| 20635 | else if (container_type->id == ZigTypeIdEnum) |
| 20636 | result = (bool)find_enum_type_field(container_type, field_name); |
| 20637 | else if (container_type->id == ZigTypeIdUnion) |
| 20638 | result = (bool)find_union_type_field(container_type, field_name); |
| 20639 | else { |
| 20640 | ir_add_error(ira, container_type_value, |
| 20641 | buf_sprintf("type '%s' does not support @memberName", buf_ptr(&container_type->name))); |
| 20642 | return ira->codegen->invalid_instruction; |
| 20643 | } |
| 20644 | return ir_build_const_bool(&ira->new_irb, |
| 20645 | instruction->base.scope, instruction->base.source_node, result); |
| 20646 | } |
| 20647 | |
| 20581 | 20648 | static IrInstruction *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstructionBreakpoint *instruction) { |
| 20582 | 20649 | IrInstruction *result = ir_build_breakpoint(&ira->new_irb, |
| 20583 | 20650 | instruction->base.scope, instruction->base.source_node); |
| ... | ... | @@ -23068,6 +23135,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23068 | 23135 | return ir_analyze_instruction_bit_offset_of(ira, (IrInstructionBitOffsetOf *)instruction); |
| 23069 | 23136 | case IrInstructionIdTypeInfo: |
| 23070 | 23137 | return ir_analyze_instruction_type_info(ira, (IrInstructionTypeInfo *) instruction); |
| 23138 | case IrInstructionIdHasField: |
| 23139 | return ir_analyze_instruction_has_field(ira, (IrInstructionHasField *) instruction); |
| 23071 | 23140 | case IrInstructionIdTypeId: |
| 23072 | 23141 | return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction); |
| 23073 | 23142 | case IrInstructionIdSetEvalBranchQuota: |
| ... | ... | @@ -23355,6 +23424,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23355 | 23424 | case IrInstructionIdByteOffsetOf: |
| 23356 | 23425 | case IrInstructionIdBitOffsetOf: |
| 23357 | 23426 | case IrInstructionIdTypeInfo: |
| 23427 | case IrInstructionIdHasField: |
| 23358 | 23428 | case IrInstructionIdTypeId: |
| 23359 | 23429 | case IrInstructionIdAlignCast: |
| 23360 | 23430 | case IrInstructionIdOpaqueType: |