@@ -719,8 +719,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldParentPtr *
719
719
return IrInstructionIdFieldParentPtr;
720
720
}
721
721
722
- static constexpr IrInstructionId ir_instruction_id(IrInstructionOffsetOf *) {
723
- return IrInstructionIdOffsetOf;
722
+ static constexpr IrInstructionId ir_instruction_id(IrInstructionByteOffsetOf *) {
723
+ return IrInstructionIdByteOffsetOf;
724
+ }
725
+
726
+ static constexpr IrInstructionId ir_instruction_id(IrInstructionBitOffsetOf *) {
727
+ return IrInstructionIdBitOffsetOf;
724
728
}
725
729
726
730
static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeInfo *) {
@@ -2645,10 +2649,23 @@ static IrInstruction *ir_build_field_parent_ptr(IrBuilder *irb, Scope *scope, As
2645
2649
return &instruction->base;
2646
2650
}
2647
2651
2648
- static IrInstruction *ir_build_offset_of(IrBuilder *irb, Scope *scope, AstNode *source_node,
2652
+ static IrInstruction *ir_build_byte_offset_of(IrBuilder *irb, Scope *scope, AstNode *source_node,
2653
+ IrInstruction *type_value, IrInstruction *field_name)
2654
+ {
2655
+ IrInstructionByteOffsetOf *instruction = ir_build_instruction<IrInstructionByteOffsetOf>(irb, scope, source_node);
2656
+ instruction->type_value = type_value;
2657
+ instruction->field_name = field_name;
2658
+
2659
+ ir_ref_instruction(type_value, irb->current_basic_block);
2660
+ ir_ref_instruction(field_name, irb->current_basic_block);
2661
+
2662
+ return &instruction->base;
2663
+ }
2664
+
2665
+ static IrInstruction *ir_build_bit_offset_of(IrBuilder *irb, Scope *scope, AstNode *source_node,
2649
2666
IrInstruction *type_value, IrInstruction *field_name)
2650
2667
{
2651
- IrInstructionOffsetOf *instruction = ir_build_instruction<IrInstructionOffsetOf >(irb, scope, source_node);
2668
+ IrInstructionBitOffsetOf *instruction = ir_build_instruction<IrInstructionBitOffsetOf >(irb, scope, source_node);
2652
2669
instruction->type_value = type_value;
2653
2670
instruction->field_name = field_name;
2654
2671
@@ -4695,7 +4712,22 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4695
4712
IrInstruction *field_parent_ptr = ir_build_field_parent_ptr(irb, scope, node, arg0_value, arg1_value, arg2_value, nullptr);
4696
4713
return ir_lval_wrap(irb, scope, field_parent_ptr, lval);
4697
4714
}
4698
- case BuiltinFnIdOffsetOf:
4715
+ case BuiltinFnIdByteOffsetOf:
4716
+ {
4717
+ AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4718
+ IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4719
+ if (arg0_value == irb->codegen->invalid_instruction)
4720
+ return arg0_value;
4721
+
4722
+ AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4723
+ IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
4724
+ if (arg1_value == irb->codegen->invalid_instruction)
4725
+ return arg1_value;
4726
+
4727
+ IrInstruction *offset_of = ir_build_byte_offset_of(irb, scope, node, arg0_value, arg1_value);
4728
+ return ir_lval_wrap(irb, scope, offset_of, lval);
4729
+ }
4730
+ case BuiltinFnIdBitOffsetOf:
4699
4731
{
4700
4732
AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4701
4733
IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
@@ -4707,7 +4739,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4707
4739
if (arg1_value == irb->codegen->invalid_instruction)
4708
4740
return arg1_value;
4709
4741
4710
- IrInstruction *offset_of = ir_build_offset_of (irb, scope, node, arg0_value, arg1_value);
4742
+ IrInstruction *offset_of = ir_build_bit_offset_of (irb, scope, node, arg0_value, arg1_value);
4711
4743
return ir_lval_wrap(irb, scope, offset_of, lval);
4712
4744
}
4713
4745
case BuiltinFnIdInlineCall:
@@ -16909,47 +16941,76 @@ static ZigType *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira,
16909
16941
return result_type;
16910
16942
}
16911
16943
16912
- static ZigType *ir_analyze_instruction_offset_of(IrAnalyze *ira,
16913
- IrInstructionOffsetOf *instruction)
16944
+ static TypeStructField *validate_byte_offset(IrAnalyze *ira,
16945
+ IrInstruction *type_value,
16946
+ IrInstruction *field_name_value,
16947
+ size_t *byte_offset)
16914
16948
{
16915
- Error err;
16916
- IrInstruction *type_value = instruction->type_value->other;
16917
16949
ZigType *container_type = ir_resolve_type(ira, type_value);
16918
16950
if (type_is_invalid(container_type))
16919
- return ira->codegen->builtin_types.entry_invalid ;
16951
+ return nullptr ;
16920
16952
16953
+ Error err;
16921
16954
if ((err = ensure_complete_type(ira->codegen, container_type)))
16922
- return ira->codegen->builtin_types.entry_invalid ;
16955
+ return nullptr ;
16923
16956
16924
- IrInstruction *field_name_value = instruction->field_name->other;
16925
16957
Buf *field_name = ir_resolve_str(ira, field_name_value);
16926
16958
if (!field_name)
16927
- return ira->codegen->builtin_types.entry_invalid ;
16959
+ return nullptr ;
16928
16960
16929
16961
if (container_type->id != ZigTypeIdStruct) {
16930
16962
ir_add_error(ira, type_value,
16931
16963
buf_sprintf("expected struct type, found '%s'", buf_ptr(&container_type->name)));
16932
- return ira->codegen->builtin_types.entry_invalid ;
16964
+ return nullptr ;
16933
16965
}
16934
16966
16935
16967
TypeStructField *field = find_struct_type_field(container_type, field_name);
16936
16968
if (field == nullptr) {
16937
16969
ir_add_error(ira, field_name_value,
16938
16970
buf_sprintf("struct '%s' has no field '%s'",
16939
- buf_ptr(&container_type->name), buf_ptr(field_name)));
16940
- return ira->codegen->builtin_types.entry_invalid ;
16971
+ buf_ptr(&container_type->name), buf_ptr(field_name)));
16972
+ return nullptr ;
16941
16973
}
16942
16974
16943
16975
if (!type_has_bits(field->type_entry)) {
16944
16976
ir_add_error(ira, field_name_value,
16945
- buf_sprintf("zero-bit field '%s' in struct '%s' has no offset",
16946
- buf_ptr(field_name), buf_ptr(&container_type->name)));
16947
- return ira->codegen->builtin_types.entry_invalid ;
16977
+ buf_sprintf("zero-bit field '%s' in struct '%s' has no offset",
16978
+ buf_ptr(field_name), buf_ptr(&container_type->name)));
16979
+ return nullptr ;
16948
16980
}
16949
- size_t byte_offset = LLVMOffsetOfElement(ira->codegen->target_data_ref, container_type->type_ref, field->gen_index);
16950
- ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
16951
- bigint_init_unsigned(&out_val->data.x_bigint, byte_offset);
16952
- return ira->codegen->builtin_types.entry_num_lit_int;
16981
+
16982
+ *byte_offset = LLVMOffsetOfElement(ira->codegen->target_data_ref, container_type->type_ref, field->gen_index);
16983
+ return field;
16984
+ }
16985
+
16986
+ static ZigType *ir_analyze_instruction_byte_offset_of(IrAnalyze *ira,
16987
+ IrInstructionByteOffsetOf *instruction)
16988
+ {
16989
+ IrInstruction *type_value = instruction->type_value->other;
16990
+ IrInstruction *field_name_value = instruction->field_name->other;
16991
+ size_t byte_offset = 0;
16992
+ if (validate_byte_offset(ira, type_value, field_name_value, &byte_offset)) {
16993
+ ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
16994
+ bigint_init_unsigned(&out_val->data.x_bigint, byte_offset);
16995
+ return ira->codegen->builtin_types.entry_num_lit_int;
16996
+ }
16997
+ return ira->codegen->builtin_types.entry_invalid;
16998
+ }
16999
+
17000
+ static ZigType *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira,
17001
+ IrInstructionBitOffsetOf *instruction)
17002
+ {
17003
+ IrInstruction *type_value = instruction->type_value->other;
17004
+ IrInstruction *field_name_value = instruction->field_name->other;
17005
+ size_t byte_offset = 0;
17006
+ TypeStructField *field = nullptr;
17007
+ if ((field = validate_byte_offset(ira, type_value, field_name_value, &byte_offset))) {
17008
+ size_t bit_offset = byte_offset * 8 + field->packed_bits_offset;
17009
+ ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
17010
+ bigint_init_unsigned(&out_val->data.x_bigint, bit_offset);
17011
+ return ira->codegen->builtin_types.entry_num_lit_int;
17012
+ }
17013
+ return ira->codegen->builtin_types.entry_invalid;
16953
17014
}
16954
17015
16955
17016
static void ensure_field_index(ZigType *type, const char *field_name, size_t index)
@@ -21362,8 +21423,10 @@ static ZigType *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *ins
21362
21423
return ir_analyze_instruction_enum_tag_name(ira, (IrInstructionTagName *)instruction);
21363
21424
case IrInstructionIdFieldParentPtr:
21364
21425
return ir_analyze_instruction_field_parent_ptr(ira, (IrInstructionFieldParentPtr *)instruction);
21365
- case IrInstructionIdOffsetOf:
21366
- return ir_analyze_instruction_offset_of(ira, (IrInstructionOffsetOf *)instruction);
21426
+ case IrInstructionIdByteOffsetOf:
21427
+ return ir_analyze_instruction_byte_offset_of(ira, (IrInstructionByteOffsetOf *)instruction);
21428
+ case IrInstructionIdBitOffsetOf:
21429
+ return ir_analyze_instruction_bit_offset_of(ira, (IrInstructionBitOffsetOf *)instruction);
21367
21430
case IrInstructionIdTypeInfo:
21368
21431
return ir_analyze_instruction_type_info(ira, (IrInstructionTypeInfo *) instruction);
21369
21432
case IrInstructionIdTypeId:
@@ -21647,7 +21710,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
21647
21710
case IrInstructionIdTypeName:
21648
21711
case IrInstructionIdTagName:
21649
21712
case IrInstructionIdFieldParentPtr:
21650
- case IrInstructionIdOffsetOf:
21713
+ case IrInstructionIdByteOffsetOf:
21714
+ case IrInstructionIdBitOffsetOf:
21651
21715
case IrInstructionIdTypeInfo:
21652
21716
case IrInstructionIdTypeId:
21653
21717
case IrInstructionIdAlignCast:
0 commit comments