| ... | @@ -851,6 +851,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeInfo *) { | ... | @@ -851,6 +851,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeInfo *) { |
| 851 | return IrInstructionIdTypeInfo; | 851 | return IrInstructionIdTypeInfo; |
| 852 | } | 852 | } |
| 853 | | 853 | |
| | 854 | static constexpr IrInstructionId ir_instruction_id(IrInstructionHasField *) { |
| | 855 | return IrInstructionIdHasField; |
| | 856 | } |
| | 857 | |
| 854 | static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeId *) { | 858 | static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeId *) { |
| 855 | return IrInstructionIdTypeId; | 859 | return IrInstructionIdTypeId; |
| 856 | } | 860 | } |
| ... | @@ -1280,6 +1284,20 @@ static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -1280,6 +1284,20 @@ static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode * |
| 1280 | return &instruction->base; | 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 | static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, | 1301 | static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1284 | IrInstruction *struct_ptr, TypeStructField *field) | 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,6 +4616,21 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4598 | | 4616 | |
| 4599 | return ir_build_load_ptr(irb, scope, node, ptr_instruction); | 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 | case BuiltinFnIdTypeInfo: | 4634 | case BuiltinFnIdTypeInfo: |
| 4602 | { | 4635 | { |
| 4603 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 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,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 | static IrInstruction *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstructionBreakpoint *instruction) { | 20648 | static IrInstruction *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstructionBreakpoint *instruction) { |
| 20582 | IrInstruction *result = ir_build_breakpoint(&ira->new_irb, | 20649 | IrInstruction *result = ir_build_breakpoint(&ira->new_irb, |
| 20583 | instruction->base.scope, instruction->base.source_node); | 20650 | instruction->base.scope, instruction->base.source_node); |
| ... | @@ -23068,6 +23135,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23068,6 +23135,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23068 | return ir_analyze_instruction_bit_offset_of(ira, (IrInstructionBitOffsetOf *)instruction); | 23135 | return ir_analyze_instruction_bit_offset_of(ira, (IrInstructionBitOffsetOf *)instruction); |
| 23069 | case IrInstructionIdTypeInfo: | 23136 | case IrInstructionIdTypeInfo: |
| 23070 | return ir_analyze_instruction_type_info(ira, (IrInstructionTypeInfo *) instruction); | 23137 | return ir_analyze_instruction_type_info(ira, (IrInstructionTypeInfo *) instruction); |
| | 23138 | case IrInstructionIdHasField: |
| | 23139 | return ir_analyze_instruction_has_field(ira, (IrInstructionHasField *) instruction); |
| 23071 | case IrInstructionIdTypeId: | 23140 | case IrInstructionIdTypeId: |
| 23072 | return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction); | 23141 | return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction); |
| 23073 | case IrInstructionIdSetEvalBranchQuota: | 23142 | case IrInstructionIdSetEvalBranchQuota: |
| ... | @@ -23355,6 +23424,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -23355,6 +23424,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23355 | case IrInstructionIdByteOffsetOf: | 23424 | case IrInstructionIdByteOffsetOf: |
| 23356 | case IrInstructionIdBitOffsetOf: | 23425 | case IrInstructionIdBitOffsetOf: |
| 23357 | case IrInstructionIdTypeInfo: | 23426 | case IrInstructionIdTypeInfo: |
| | 23427 | case IrInstructionIdHasField: |
| 23358 | case IrInstructionIdTypeId: | 23428 | case IrInstructionIdTypeId: |
| 23359 | case IrInstructionIdAlignCast: | 23429 | case IrInstructionIdAlignCast: |
| 23360 | case IrInstructionIdOpaqueType: | 23430 | case IrInstructionIdOpaqueType: |