authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-19 22:43:41+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2018-04-19 22:43:41+02:00
logcc35f085cad8a8da1b08ecaf6681f097aca7b604
tree2d64dc990fb6897a33a99117c034f125e8a96800
parent06909ceaab8ecb33d1f41049870797a3ae721610
parent72bf9d90cc5fa4384ca7db1e5bbd4b9445e63bd3
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #934 from zig-lang/adding-builtin-field

Added @field builtin function

6 files changed, 227 insertions(+), 83 deletions(-)

doc/langref.html.in+5-1
......@@ -4412,6 +4412,10 @@ fn add(a: i32, b: i32) i32 { return a + b; }
44124412 It does not include functions, variables, or constants.
44134413 </p>
44144414 {#header_close#}
4415 {#header_open|@field#}
4416 <pre><code class="zig">@field(lhs: var, comptime field_name: []const u8) -&gt; (field)</code></pre>
4417 <p>Preforms field access equivalent to <code>lhs.-&gtfield_name-&lt</code>.</p>
4418 {#header_close#}
44154419 {#header_open|@memberType#}
44164420 <pre><code class="zig">@memberType(comptime T: type, comptime index: usize) -&gt; type</code></pre>
44174421 <p>Returns the field type of a struct or union.</p>
......@@ -6064,7 +6068,7 @@ hljs.registerLanguage("zig", function(t) {
60646068 a = t.IR + "\\s*\\(",
60656069 c = {
60666070 keyword: "const align var extern stdcallcc nakedcc volatile export pub noalias inline struct packed enum union break return try catch test continue unreachable comptime and or asm defer errdefer if else switch while for fn use bool f32 f64 void type noreturn error i8 u8 i16 u16 i32 u32 i64 u64 isize usize i8w u8w i16w i32w u32w i64w u64w isizew usizew c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong",
6067 built_in: "atomicLoad breakpoint returnAddress frameAddress fieldParentPtr setFloatMode IntType OpaqueType compileError compileLog setCold setRuntimeSafety setEvalBranchQuota offsetOf memcpy inlineCall setGlobalLinkage setGlobalSection divTrunc divFloor enumTagName intToPtr ptrToInt panic canImplicitCast ptrCast bitCast rem mod memset sizeOf alignOf alignCast maxValue minValue memberCount memberName memberType typeOf addWithOverflow subWithOverflow mulWithOverflow shlWithOverflow shlExact shrExact cInclude cDefine cUndef ctz clz import cImport errorName embedFile cmpxchgStrong cmpxchgWeak fence divExact truncate atomicRmw sqrt",
6071 built_in: "atomicLoad breakpoint returnAddress frameAddress fieldParentPtr setFloatMode IntType OpaqueType compileError compileLog setCold setRuntimeSafety setEvalBranchQuota offsetOf memcpy inlineCall setGlobalLinkage setGlobalSection divTrunc divFloor enumTagName intToPtr ptrToInt panic canImplicitCast ptrCast bitCast rem mod memset sizeOf alignOf alignCast maxValue minValue memberCount memberName memberType typeOf addWithOverflow subWithOverflow mulWithOverflow shlWithOverflow shlExact shrExact cInclude cDefine cUndef ctz clz import cImport errorName embedFile cmpxchgStrong cmpxchgWeak fence divExact truncate atomicRmw sqrt field",
60686072 literal: "true false null undefined"
60696073 },
60706074 n = [e, t.CLCM, t.CBCM, s, r];
src/all_types.hpp+3-1
......@@ -1292,6 +1292,7 @@ enum BuiltinFnId {
12921292 BuiltinFnIdMemberCount,
12931293 BuiltinFnIdMemberType,
12941294 BuiltinFnIdMemberName,
1295 BuiltinFnIdField,
12951296 BuiltinFnIdTypeof,
12961297 BuiltinFnIdAddWithOverflow,
12971298 BuiltinFnIdSubWithOverflow,
......@@ -2225,7 +2226,8 @@ struct IrInstructionFieldPtr {
22252226 IrInstruction base;
22262227
22272228 IrInstruction *container_ptr;
2228 Buf *field_name;
2229 Buf *field_name_buffer;
2230 IrInstruction *field_name_expr;
22292231 bool is_const;
22302232};
22312233
src/codegen.cpp+1-1
......@@ -6114,6 +6114,7 @@ static void define_builtin_fns(CodeGen *g) {
61146114 create_builtin_fn(g, BuiltinFnIdMemberCount, "memberCount", 1);
61156115 create_builtin_fn(g, BuiltinFnIdMemberType, "memberType", 2);
61166116 create_builtin_fn(g, BuiltinFnIdMemberName, "memberName", 2);
6117 create_builtin_fn(g, BuiltinFnIdField, "field", 2);
61176118 create_builtin_fn(g, BuiltinFnIdTypeof, "typeOf", 1); // TODO rename to TypeOf
61186119 create_builtin_fn(g, BuiltinFnIdAddWithOverflow, "addWithOverflow", 4);
61196120 create_builtin_fn(g, BuiltinFnIdSubWithOverflow, "subWithOverflow", 4);
......@@ -7185,4 +7186,3 @@ PackageTableEntry *codegen_create_package(CodeGen *g, const char *root_src_dir,
71857186 }
71867187 return pkg;
71877188}
7188
src/ir.cpp+182-77
......@@ -111,6 +111,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
111111static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
112112 VariableTableEntry *var, bool is_const_ptr, bool is_volatile_ptr);
113113static TypeTableEntry *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op);
114static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval);
114115
115116ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) {
116117 assert(const_val->type->id == TypeTableEntryIdPointer);
......@@ -1033,12 +1034,27 @@ static IrInstruction *ir_build_elem_ptr_from(IrBuilder *irb, IrInstruction *old_
10331034 return new_instruction;
10341035}
10351036
1037static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node,
1038 IrInstruction *container_ptr, IrInstruction *field_name_expr)
1039{
1040 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node);
1041 instruction->container_ptr = container_ptr;
1042 instruction->field_name_buffer = nullptr;
1043 instruction->field_name_expr = field_name_expr;
1044
1045 ir_ref_instruction(container_ptr, irb->current_basic_block);
1046 ir_ref_instruction(field_name_expr, irb->current_basic_block);
1047
1048 return &instruction->base;
1049}
1050
10361051static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
10371052 IrInstruction *container_ptr, Buf *field_name)
10381053{
10391054 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node);
10401055 instruction->container_ptr = container_ptr;
1041 instruction->field_name = field_name;
1056 instruction->field_name_buffer = field_name;
1057 instruction->field_name_expr = nullptr;
10421058
10431059 ir_ref_instruction(container_ptr, irb->current_basic_block);
10441060
......@@ -3524,7 +3540,7 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode
35243540 return ir_build_load_ptr(irb, scope, node, ptr_instruction);
35253541}
35263542
3527static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {
3543static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode *node) {
35283544 assert(node->type == NodeTypeFieldAccessExpr);
35293545
35303546 AstNode *container_ref_node = node->data.field_access_expr.struct_expr;
......@@ -3534,11 +3550,7 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode
35343550 if (container_ref_instruction == irb->codegen->invalid_instruction)
35353551 return container_ref_instruction;
35363552
3537 IrInstruction *ptr_instruction = ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name);
3538 if (lval.is_ptr)
3539 return ptr_instruction;
3540
3541 return ir_build_load_ptr(irb, scope, node, ptr_instruction);
3553 return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name);
35423554}
35433555
35443556static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *node, IrOverflowOp op) {
......@@ -3569,7 +3581,7 @@ static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *
35693581 return ir_build_overflow_op(irb, scope, node, op, type_value, op1, op2, result_ptr, nullptr);
35703582}
35713583
3572static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node) {
3584static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {
35733585 assert(node->type == NodeTypeFnCallExpr);
35743586
35753587 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
......@@ -3601,7 +3613,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36013613 IrInstruction *arg = ir_gen_node(irb, arg_node, scope);
36023614 if (arg == irb->codegen->invalid_instruction)
36033615 return arg;
3604 return ir_build_typeof(irb, scope, node, arg);
3616
3617 IrInstruction *type_of = ir_build_typeof(irb, scope, node, arg);
3618 return ir_lval_wrap(irb, scope, type_of, lval);
36053619 }
36063620 case BuiltinFnIdSetCold:
36073621 {
......@@ -3610,7 +3624,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36103624 if (arg0_value == irb->codegen->invalid_instruction)
36113625 return arg0_value;
36123626
3613 return ir_build_set_cold(irb, scope, node, arg0_value);
3627 IrInstruction *set_cold = ir_build_set_cold(irb, scope, node, arg0_value);
3628 return ir_lval_wrap(irb, scope, set_cold, lval);
36143629 }
36153630 case BuiltinFnIdSetRuntimeSafety:
36163631 {
......@@ -3619,7 +3634,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36193634 if (arg0_value == irb->codegen->invalid_instruction)
36203635 return arg0_value;
36213636
3622 return ir_build_set_runtime_safety(irb, scope, node, arg0_value);
3637 IrInstruction *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value);
3638 return ir_lval_wrap(irb, scope, set_safety, lval);
36233639 }
36243640 case BuiltinFnIdSetFloatMode:
36253641 {
......@@ -3633,7 +3649,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36333649 if (arg1_value == irb->codegen->invalid_instruction)
36343650 return arg1_value;
36353651
3636 return ir_build_set_float_mode(irb, scope, node, arg0_value, arg1_value);
3652 IrInstruction *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value, arg1_value);
3653 return ir_lval_wrap(irb, scope, set_float_mode, lval);
36373654 }
36383655 case BuiltinFnIdSizeof:
36393656 {
......@@ -3642,7 +3659,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36423659 if (arg0_value == irb->codegen->invalid_instruction)
36433660 return arg0_value;
36443661
3645 return ir_build_size_of(irb, scope, node, arg0_value);
3662 IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value);
3663 return ir_lval_wrap(irb, scope, size_of, lval);
36463664 }
36473665 case BuiltinFnIdCtz:
36483666 {
......@@ -3651,7 +3669,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36513669 if (arg0_value == irb->codegen->invalid_instruction)
36523670 return arg0_value;
36533671
3654 return ir_build_ctz(irb, scope, node, arg0_value);
3672 IrInstruction *ctz = ir_build_ctz(irb, scope, node, arg0_value);
3673 return ir_lval_wrap(irb, scope, ctz, lval);
36553674 }
36563675 case BuiltinFnIdClz:
36573676 {
......@@ -3660,7 +3679,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36603679 if (arg0_value == irb->codegen->invalid_instruction)
36613680 return arg0_value;
36623681
3663 return ir_build_clz(irb, scope, node, arg0_value);
3682 IrInstruction *clz = ir_build_clz(irb, scope, node, arg0_value);
3683 return ir_lval_wrap(irb, scope, clz, lval);
36643684 }
36653685 case BuiltinFnIdImport:
36663686 {
......@@ -3669,11 +3689,13 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36693689 if (arg0_value == irb->codegen->invalid_instruction)
36703690 return arg0_value;
36713691
3672 return ir_build_import(irb, scope, node, arg0_value);
3692 IrInstruction *import = ir_build_import(irb, scope, node, arg0_value);
3693 return ir_lval_wrap(irb, scope, import, lval);
36733694 }
36743695 case BuiltinFnIdCImport:
36753696 {
3676 return ir_build_c_import(irb, scope, node);
3697 IrInstruction *c_import = ir_build_c_import(irb, scope, node);
3698 return ir_lval_wrap(irb, scope, c_import, lval);
36773699 }
36783700 case BuiltinFnIdCInclude:
36793701 {
......@@ -3687,7 +3709,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36873709 return irb->codegen->invalid_instruction;
36883710 }
36893711
3690 return ir_build_c_include(irb, scope, node, arg0_value);
3712 IrInstruction *c_include = ir_build_c_include(irb, scope, node, arg0_value);
3713 return ir_lval_wrap(irb, scope, c_include, lval);
36913714 }
36923715 case BuiltinFnIdCDefine:
36933716 {
......@@ -3706,7 +3729,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
37063729 return irb->codegen->invalid_instruction;
37073730 }
37083731
3709 return ir_build_c_define(irb, scope, node, arg0_value, arg1_value);
3732 IrInstruction *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value);
3733 return ir_lval_wrap(irb, scope, c_define, lval);
37103734 }
37113735 case BuiltinFnIdCUndef:
37123736 {
......@@ -3720,7 +3744,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
37203744 return irb->codegen->invalid_instruction;
37213745 }
37223746
3723 return ir_build_c_undef(irb, scope, node, arg0_value);
3747 IrInstruction *c_undef = ir_build_c_undef(irb, scope, node, arg0_value);
3748 return ir_lval_wrap(irb, scope, c_undef, lval);
37243749 }
37253750 case BuiltinFnIdMaxValue:
37263751 {
......@@ -3729,7 +3754,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
37293754 if (arg0_value == irb->codegen->invalid_instruction)
37303755 return arg0_value;
37313756
3732 return ir_build_max_value(irb, scope, node, arg0_value);
3757 IrInstruction *max_value = ir_build_max_value(irb, scope, node, arg0_value);
3758 return ir_lval_wrap(irb, scope, max_value, lval);
37333759 }
37343760 case BuiltinFnIdMinValue:
37353761 {
......@@ -3738,7 +3764,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
37383764 if (arg0_value == irb->codegen->invalid_instruction)
37393765 return arg0_value;
37403766
3741 return ir_build_min_value(irb, scope, node, arg0_value);
3767 IrInstruction *min_value = ir_build_min_value(irb, scope, node, arg0_value);
3768 return ir_lval_wrap(irb, scope, min_value, lval);
37423769 }
37433770 case BuiltinFnIdCompileErr:
37443771 {
......@@ -3747,7 +3774,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
37473774 if (arg0_value == irb->codegen->invalid_instruction)
37483775 return arg0_value;
37493776
3750 return ir_build_compile_err(irb, scope, node, arg0_value);
3777 IrInstruction *compile_err = ir_build_compile_err(irb, scope, node, arg0_value);
3778 return ir_lval_wrap(irb, scope, compile_err, lval);
37513779 }
37523780 case BuiltinFnIdCompileLog:
37533781 {
......@@ -3760,7 +3788,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
37603788 return irb->codegen->invalid_instruction;
37613789 }
37623790
3763 return ir_build_compile_log(irb, scope, node, actual_param_count, args);
3791 IrInstruction *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args);
3792 return ir_lval_wrap(irb, scope, compile_log, lval);
37643793 }
37653794 case BuiltinFnIdErrName:
37663795 {
......@@ -3769,7 +3798,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
37693798 if (arg0_value == irb->codegen->invalid_instruction)
37703799 return arg0_value;
37713800
3772 return ir_build_err_name(irb, scope, node, arg0_value);
3801 IrInstruction *err_name = ir_build_err_name(irb, scope, node, arg0_value);
3802 return ir_lval_wrap(irb, scope, err_name, lval);
37733803 }
37743804 case BuiltinFnIdEmbedFile:
37753805 {
......@@ -3778,7 +3808,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
37783808 if (arg0_value == irb->codegen->invalid_instruction)
37793809 return arg0_value;
37803810
3781 return ir_build_embed_file(irb, scope, node, arg0_value);
3811 IrInstruction *embed_file = ir_build_embed_file(irb, scope, node, arg0_value);
3812 return ir_lval_wrap(irb, scope, embed_file, lval);
37823813 }
37833814 case BuiltinFnIdCmpxchgWeak:
37843815 case BuiltinFnIdCmpxchgStrong:
......@@ -3813,9 +3844,10 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
38133844 if (arg5_value == irb->codegen->invalid_instruction)
38143845 return arg5_value;
38153846
3816 return ir_build_cmpxchg(irb, scope, node, arg0_value, arg1_value,
3847 IrInstruction *cmpxchg = ir_build_cmpxchg(irb, scope, node, arg0_value, arg1_value,
38173848 arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak),
38183849 nullptr, AtomicOrderUnordered, AtomicOrderUnordered);
3850 return ir_lval_wrap(irb, scope, cmpxchg, lval);
38193851 }
38203852 case BuiltinFnIdFence:
38213853 {
......@@ -3824,7 +3856,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
38243856 if (arg0_value == irb->codegen->invalid_instruction)
38253857 return arg0_value;
38263858
3827 return ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered);
3859 IrInstruction *fence = ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered);
3860 return ir_lval_wrap(irb, scope, fence, lval);
38283861 }
38293862 case BuiltinFnIdDivExact:
38303863 {
......@@ -3838,7 +3871,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
38383871 if (arg1_value == irb->codegen->invalid_instruction)
38393872 return arg1_value;
38403873
3841 return ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true);
3874 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true);
3875 return ir_lval_wrap(irb, scope, bin_op, lval);
38423876 }
38433877 case BuiltinFnIdDivTrunc:
38443878 {
......@@ -3852,7 +3886,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
38523886 if (arg1_value == irb->codegen->invalid_instruction)
38533887 return arg1_value;
38543888
3855 return ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true);
3889 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true);
3890 return ir_lval_wrap(irb, scope, bin_op, lval);
38563891 }
38573892 case BuiltinFnIdDivFloor:
38583893 {
......@@ -3866,7 +3901,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
38663901 if (arg1_value == irb->codegen->invalid_instruction)
38673902 return arg1_value;
38683903
3869 return ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true);
3904 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true);
3905 return ir_lval_wrap(irb, scope, bin_op, lval);
38703906 }
38713907 case BuiltinFnIdRem:
38723908 {
......@@ -3880,7 +3916,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
38803916 if (arg1_value == irb->codegen->invalid_instruction)
38813917 return arg1_value;
38823918
3883 return ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true);
3919 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true);
3920 return ir_lval_wrap(irb, scope, bin_op, lval);
38843921 }
38853922 case BuiltinFnIdMod:
38863923 {
......@@ -3894,7 +3931,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
38943931 if (arg1_value == irb->codegen->invalid_instruction)
38953932 return arg1_value;
38963933
3897 return ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true);
3934 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true);
3935 return ir_lval_wrap(irb, scope, bin_op, lval);
38983936 }
38993937 case BuiltinFnIdSqrt:
39003938 {
......@@ -3908,7 +3946,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
39083946 if (arg1_value == irb->codegen->invalid_instruction)
39093947 return arg1_value;
39103948
3911 return ir_build_sqrt(irb, scope, node, arg0_value, arg1_value);
3949 IrInstruction *ir_sqrt = ir_build_sqrt(irb, scope, node, arg0_value, arg1_value);
3950 return ir_lval_wrap(irb, scope, ir_sqrt, lval);
39123951 }
39133952 case BuiltinFnIdTruncate:
39143953 {
......@@ -3922,7 +3961,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
39223961 if (arg1_value == irb->codegen->invalid_instruction)
39233962 return arg1_value;
39243963
3925 return ir_build_truncate(irb, scope, node, arg0_value, arg1_value);
3964 IrInstruction *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value);
3965 return ir_lval_wrap(irb, scope, truncate, lval);
39263966 }
39273967 case BuiltinFnIdIntType:
39283968 {
......@@ -3936,7 +3976,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
39363976 if (arg1_value == irb->codegen->invalid_instruction)
39373977 return arg1_value;
39383978
3939 return ir_build_int_type(irb, scope, node, arg0_value, arg1_value);
3979 IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value);
3980 return ir_lval_wrap(irb, scope, int_type, lval);
39403981 }
39413982 case BuiltinFnIdMemcpy:
39423983 {
......@@ -3955,7 +3996,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
39553996 if (arg2_value == irb->codegen->invalid_instruction)
39563997 return arg2_value;
39573998
3958 return ir_build_memcpy(irb, scope, node, arg0_value, arg1_value, arg2_value);
3999 IrInstruction *ir_memcpy = ir_build_memcpy(irb, scope, node, arg0_value, arg1_value, arg2_value);
4000 return ir_lval_wrap(irb, scope, ir_memcpy, lval);
39594001 }
39604002 case BuiltinFnIdMemset:
39614003 {
......@@ -3974,7 +4016,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
39744016 if (arg2_value == irb->codegen->invalid_instruction)
39754017 return arg2_value;
39764018
3977 return ir_build_memset(irb, scope, node, arg0_value, arg1_value, arg2_value);
4019 IrInstruction *ir_memset = ir_build_memset(irb, scope, node, arg0_value, arg1_value, arg2_value);
4020 return ir_lval_wrap(irb, scope, ir_memset, lval);
39784021 }
39794022 case BuiltinFnIdMemberCount:
39804023 {
......@@ -3983,7 +4026,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
39834026 if (arg0_value == irb->codegen->invalid_instruction)
39844027 return arg0_value;
39854028
3986 return ir_build_member_count(irb, scope, node, arg0_value);
4029 IrInstruction *member_count = ir_build_member_count(irb, scope, node, arg0_value);
4030 return ir_lval_wrap(irb, scope, member_count, lval);
39874031 }
39884032 case BuiltinFnIdMemberType:
39894033 {
......@@ -3998,7 +4042,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
39984042 return arg1_value;
39994043
40004044
4001 return ir_build_member_type(irb, scope, node, arg0_value, arg1_value);
4045 IrInstruction *member_type = ir_build_member_type(irb, scope, node, arg0_value, arg1_value);
4046 return ir_lval_wrap(irb, scope, member_type, lval);
40024047 }
40034048 case BuiltinFnIdMemberName:
40044049 {
......@@ -4013,14 +4058,34 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40134058 return arg1_value;
40144059
40154060
4016 return ir_build_member_name(irb, scope, node, arg0_value, arg1_value);
4061 IrInstruction *member_name = ir_build_member_name(irb, scope, node, arg0_value, arg1_value);
4062 return ir_lval_wrap(irb, scope, member_name, lval);
4063 }
4064 case BuiltinFnIdField:
4065 {
4066 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4067 IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LVAL_PTR);
4068 if (arg0_value == irb->codegen->invalid_instruction)
4069 return arg0_value;
4070
4071 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4072 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
4073 if (arg1_value == irb->codegen->invalid_instruction)
4074 return arg1_value;
4075
4076 IrInstruction *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, arg0_value, arg1_value);
4077
4078 if (lval.is_ptr)
4079 return ptr_instruction;
4080
4081 return ir_build_load_ptr(irb, scope, node, ptr_instruction);
40174082 }
40184083 case BuiltinFnIdBreakpoint:
4019 return ir_build_breakpoint(irb, scope, node);
4084 return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval);
40204085 case BuiltinFnIdReturnAddress:
4021 return ir_build_return_address(irb, scope, node);
4086 return ir_lval_wrap(irb, scope, ir_build_return_address(irb, scope, node), lval);
40224087 case BuiltinFnIdFrameAddress:
4023 return ir_build_frame_address(irb, scope, node);
4088 return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval);
40244089 case BuiltinFnIdAlignOf:
40254090 {
40264091 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
......@@ -4028,16 +4093,17 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40284093 if (arg0_value == irb->codegen->invalid_instruction)
40294094 return arg0_value;
40304095
4031 return ir_build_align_of(irb, scope, node, arg0_value);
4096 IrInstruction *align_of = ir_build_align_of(irb, scope, node, arg0_value);
4097 return ir_lval_wrap(irb, scope, align_of, lval);
40324098 }
40334099 case BuiltinFnIdAddWithOverflow:
4034 return ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd);
4100 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd), lval);
40354101 case BuiltinFnIdSubWithOverflow:
4036 return ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub);
4102 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub), lval);
40374103 case BuiltinFnIdMulWithOverflow:
4038 return ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul);
4104 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul), lval);
40394105 case BuiltinFnIdShlWithOverflow:
4040 return ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl);
4106 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl), lval);
40414107 case BuiltinFnIdTypeName:
40424108 {
40434109 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
......@@ -4045,7 +4111,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40454111 if (arg0_value == irb->codegen->invalid_instruction)
40464112 return arg0_value;
40474113
4048 return ir_build_type_name(irb, scope, node, arg0_value);
4114 IrInstruction *type_name = ir_build_type_name(irb, scope, node, arg0_value);
4115 return ir_lval_wrap(irb, scope, type_name, lval);
40494116 }
40504117 case BuiltinFnIdCanImplicitCast:
40514118 {
......@@ -4059,7 +4126,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40594126 if (arg1_value == irb->codegen->invalid_instruction)
40604127 return arg1_value;
40614128
4062 return ir_build_can_implicit_cast(irb, scope, node, arg0_value, arg1_value);
4129 IrInstruction *can_implicit_cast = ir_build_can_implicit_cast(irb, scope, node, arg0_value, arg1_value);
4130 return ir_lval_wrap(irb, scope, can_implicit_cast, lval);
40634131 }
40644132 case BuiltinFnIdPanic:
40654133 {
......@@ -4068,7 +4136,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40684136 if (arg0_value == irb->codegen->invalid_instruction)
40694137 return arg0_value;
40704138
4071 return ir_build_panic(irb, scope, node, arg0_value);
4139 IrInstruction *panic = ir_build_panic(irb, scope, node, arg0_value);
4140 return ir_lval_wrap(irb, scope, panic, lval);
40724141 }
40734142 case BuiltinFnIdPtrCast:
40744143 {
......@@ -4082,7 +4151,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40824151 if (arg1_value == irb->codegen->invalid_instruction)
40834152 return arg1_value;
40844153
4085 return ir_build_ptr_cast(irb, scope, node, arg0_value, arg1_value);
4154 IrInstruction *ptr_cast = ir_build_ptr_cast(irb, scope, node, arg0_value, arg1_value);
4155 return ir_lval_wrap(irb, scope, ptr_cast, lval);
40864156 }
40874157 case BuiltinFnIdBitCast:
40884158 {
......@@ -4096,7 +4166,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40964166 if (arg1_value == irb->codegen->invalid_instruction)
40974167 return arg1_value;
40984168
4099 return ir_build_bit_cast(irb, scope, node, arg0_value, arg1_value);
4169 IrInstruction *bit_cast = ir_build_bit_cast(irb, scope, node, arg0_value, arg1_value);
4170 return ir_lval_wrap(irb, scope, bit_cast, lval);
41004171 }
41014172 case BuiltinFnIdIntToPtr:
41024173 {
......@@ -4110,7 +4181,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41104181 if (arg1_value == irb->codegen->invalid_instruction)
41114182 return arg1_value;
41124183
4113 return ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value);
4184 IrInstruction *int_to_ptr = ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value);
4185 return ir_lval_wrap(irb, scope, int_to_ptr, lval);
41144186 }
41154187 case BuiltinFnIdPtrToInt:
41164188 {
......@@ -4119,7 +4191,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41194191 if (arg0_value == irb->codegen->invalid_instruction)
41204192 return arg0_value;
41214193
4122 return ir_build_ptr_to_int(irb, scope, node, arg0_value);
4194 IrInstruction *ptr_to_int = ir_build_ptr_to_int(irb, scope, node, arg0_value);
4195 return ir_lval_wrap(irb, scope, ptr_to_int, lval);
41234196 }
41244197 case BuiltinFnIdTagName:
41254198 {
......@@ -4129,7 +4202,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41294202 return arg0_value;
41304203
41314204 IrInstruction *actual_tag = ir_build_union_tag(irb, scope, node, arg0_value);
4132 return ir_build_tag_name(irb, scope, node, actual_tag);
4205 IrInstruction *tag_name = ir_build_tag_name(irb, scope, node, actual_tag);
4206 return ir_lval_wrap(irb, scope, tag_name, lval);
41334207 }
41344208 case BuiltinFnIdTagType:
41354209 {
......@@ -4138,7 +4212,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41384212 if (arg0_value == irb->codegen->invalid_instruction)
41394213 return arg0_value;
41404214
4141 return ir_build_tag_type(irb, scope, node, arg0_value);
4215 IrInstruction *tag_type = ir_build_tag_type(irb, scope, node, arg0_value);
4216 return ir_lval_wrap(irb, scope, tag_type, lval);
41424217 }
41434218 case BuiltinFnIdFieldParentPtr:
41444219 {
......@@ -4157,7 +4232,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41574232 if (arg2_value == irb->codegen->invalid_instruction)
41584233 return arg2_value;
41594234
4160 return ir_build_field_parent_ptr(irb, scope, node, arg0_value, arg1_value, arg2_value, nullptr);
4235 IrInstruction *field_parent_ptr = ir_build_field_parent_ptr(irb, scope, node, arg0_value, arg1_value, arg2_value, nullptr);
4236 return ir_lval_wrap(irb, scope, field_parent_ptr, lval);
41614237 }
41624238 case BuiltinFnIdOffsetOf:
41634239 {
......@@ -4171,7 +4247,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41714247 if (arg1_value == irb->codegen->invalid_instruction)
41724248 return arg1_value;
41734249
4174 return ir_build_offset_of(irb, scope, node, arg0_value, arg1_value);
4250 IrInstruction *offset_of = ir_build_offset_of(irb, scope, node, arg0_value, arg1_value);
4251 return ir_lval_wrap(irb, scope, offset_of, lval);
41754252 }
41764253 case BuiltinFnIdInlineCall:
41774254 case BuiltinFnIdNoInlineCall:
......@@ -4197,7 +4274,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41974274 }
41984275 FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever;
41994276
4200 return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr);
4277 IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr);
4278 return ir_lval_wrap(irb, scope, call, lval);
42014279 }
42024280 case BuiltinFnIdTypeId:
42034281 {
......@@ -4206,7 +4284,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42064284 if (arg0_value == irb->codegen->invalid_instruction)
42074285 return arg0_value;
42084286
4209 return ir_build_type_id(irb, scope, node, arg0_value);
4287 IrInstruction *type_id = ir_build_type_id(irb, scope, node, arg0_value);
4288 return ir_lval_wrap(irb, scope, type_id, lval);
42104289 }
42114290 case BuiltinFnIdShlExact:
42124291 {
......@@ -4220,7 +4299,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42204299 if (arg1_value == irb->codegen->invalid_instruction)
42214300 return arg1_value;
42224301
4223 return ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true);
4302 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true);
4303 return ir_lval_wrap(irb, scope, bin_op, lval);
42244304 }
42254305 case BuiltinFnIdShrExact:
42264306 {
......@@ -4234,7 +4314,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42344314 if (arg1_value == irb->codegen->invalid_instruction)
42354315 return arg1_value;
42364316
4237 return ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true);
4317 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true);
4318 return ir_lval_wrap(irb, scope, bin_op, lval);
42384319 }
42394320 case BuiltinFnIdSetEvalBranchQuota:
42404321 {
......@@ -4243,7 +4324,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42434324 if (arg0_value == irb->codegen->invalid_instruction)
42444325 return arg0_value;
42454326
4246 return ir_build_set_eval_branch_quota(irb, scope, node, arg0_value);
4327 IrInstruction *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value);
4328 return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval);
42474329 }
42484330 case BuiltinFnIdAlignCast:
42494331 {
......@@ -4257,10 +4339,14 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42574339 if (arg1_value == irb->codegen->invalid_instruction)
42584340 return arg1_value;
42594341
4260 return ir_build_align_cast(irb, scope, node, arg0_value, arg1_value);
4342 IrInstruction *align_cast = ir_build_align_cast(irb, scope, node, arg0_value, arg1_value);
4343 return ir_lval_wrap(irb, scope, align_cast, lval);
42614344 }
42624345 case BuiltinFnIdOpaqueType:
4263 return ir_build_opaque_type(irb, scope, node);
4346 {
4347 IrInstruction *opaque_type = ir_build_opaque_type(irb, scope, node);
4348 return ir_lval_wrap(irb, scope, opaque_type, lval);
4349 }
42644350 case BuiltinFnIdSetAlignStack:
42654351 {
42664352 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
......@@ -4268,7 +4354,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42684354 if (arg0_value == irb->codegen->invalid_instruction)
42694355 return arg0_value;
42704356
4271 return ir_build_set_align_stack(irb, scope, node, arg0_value);
4357 IrInstruction *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value);
4358 return ir_lval_wrap(irb, scope, set_align_stack, lval);
42724359 }
42734360 case BuiltinFnIdArgType:
42744361 {
......@@ -4282,7 +4369,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42824369 if (arg1_value == irb->codegen->invalid_instruction)
42834370 return arg1_value;
42844371
4285 return ir_build_arg_type(irb, scope, node, arg0_value, arg1_value);
4372 IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value);
4373 return ir_lval_wrap(irb, scope, arg_type, lval);
42864374 }
42874375 case BuiltinFnIdExport:
42884376 {
......@@ -4301,11 +4389,13 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
43014389 if (arg2_value == irb->codegen->invalid_instruction)
43024390 return arg2_value;
43034391
4304 return ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value);
4392 IrInstruction *ir_export = ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value);
4393 return ir_lval_wrap(irb, scope, ir_export, lval);
43054394 }
43064395 case BuiltinFnIdErrorReturnTrace:
43074396 {
4308 return ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::Null);
4397 IrInstruction *error_return_trace = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::Null);
4398 return ir_lval_wrap(irb, scope, error_return_trace, lval);
43094399 }
43104400 case BuiltinFnIdAtomicRmw:
43114401 {
......@@ -4364,11 +4454,11 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
43644454 zig_unreachable();
43654455}
43664456
4367static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node) {
4457static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {
43684458 assert(node->type == NodeTypeFnCallExpr);
43694459
43704460 if (node->data.fn_call_expr.is_builtin)
4371 return ir_gen_builtin_fn_call(irb, scope, node);
4461 return ir_gen_builtin_fn_call(irb, scope, node, lval);
43724462
43734463 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
43744464 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope);
......@@ -4394,7 +4484,8 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node
43944484 }
43954485 }
43964486
4397 return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, is_async, async_allocator);
4487 IrInstruction *fn_call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, is_async, async_allocator);
4488 return ir_lval_wrap(irb, scope, fn_call, lval);
43984489}
43994490
44004491static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
......@@ -6410,7 +6501,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
64106501 case NodeTypeSymbol:
64116502 return ir_gen_symbol(irb, scope, node, lval);
64126503 case NodeTypeFnCallExpr:
6413 return ir_lval_wrap(irb, scope, ir_gen_fn_call(irb, scope, node), lval);
6504 return ir_gen_fn_call(irb, scope, node, lval);
64146505 case NodeTypeIfBoolExpr:
64156506 return ir_lval_wrap(irb, scope, ir_gen_if_bool_expr(irb, scope, node), lval);
64166507 case NodeTypePrefixOpExpr:
......@@ -6430,7 +6521,13 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
64306521 case NodeTypeReturnExpr:
64316522 return ir_gen_return(irb, scope, node, lval);
64326523 case NodeTypeFieldAccessExpr:
6433 return ir_gen_field_access(irb, scope, node, lval);
6524 {
6525 IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node);
6526 if (lval.is_ptr)
6527 return ptr_instruction;
6528
6529 return ir_build_load_ptr(irb, scope, node, ptr_instruction);
6530 }
64346531 case NodeTypeThisLiteral:
64356532 return ir_lval_wrap(irb, scope, ir_gen_this_literal(irb, scope, node), lval);
64366533 case NodeTypeBoolLiteral:
......@@ -13458,7 +13555,15 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
1345813555 zig_unreachable();
1345913556 }
1346013557
13461 Buf *field_name = field_ptr_instruction->field_name;
13558 Buf *field_name = field_ptr_instruction->field_name_buffer;
13559 if (!field_name) {
13560 IrInstruction *field_name_expr = field_ptr_instruction->field_name_expr->other;
13561 field_name = ir_resolve_str(ira, field_name_expr);
13562 if (!field_name)
13563 return ira->codegen->builtin_types.entry_invalid;
13564 }
13565
13566
1346213567 AstNode *source_node = field_ptr_instruction->base.source_node;
1346313568
1346413569 if (type_is_invalid(container_type)) {
src/ir_print.cpp+12-3
......@@ -358,9 +358,18 @@ static void ir_print_ptr_type_child(IrPrint *irp, IrInstructionPtrTypeChild *ins
358358}
359359
360360static void ir_print_field_ptr(IrPrint *irp, IrInstructionFieldPtr *instruction) {
361 fprintf(irp->f, "fieldptr ");
362 ir_print_other_instruction(irp, instruction->container_ptr);
363 fprintf(irp->f, ".%s", buf_ptr(instruction->field_name));
361 if (instruction->field_name_buffer) {
362 fprintf(irp->f, "fieldptr ");
363 ir_print_other_instruction(irp, instruction->container_ptr);
364 fprintf(irp->f, ".%s", buf_ptr(instruction->field_name_buffer));
365 } else {
366 assert(instruction->field_name_expr);
367 fprintf(irp->f, "@field(");
368 ir_print_other_instruction(irp, instruction->container_ptr);
369 fprintf(irp->f, ", ");
370 ir_print_other_instruction(irp, instruction->field_name_expr);
371 fprintf(irp->f, ")");
372 }
364373}
365374
366375static void ir_print_struct_field_ptr(IrPrint *irp, IrInstructionStructFieldPtr *instruction) {
test/cases/reflection.zig+24
......@@ -1,5 +1,6 @@
11const assert = @import("std").debug.assert;
22const mem = @import("std").mem;
3const reflection = this;
34
45test "reflection: array, pointer, nullable, error union type child" {
56 comptime {
......@@ -56,7 +57,30 @@ test "reflection: enum member types and names" {
5657
5758}
5859
60test "reflection: @field" {
61 var f = Foo {
62 .one = 42,
63 .two = true,
64 .three = void{},
65 };
66
67 assert(f.one == f.one);
68 assert(@field(f, "o" ++ "ne") == f.one);
69 assert(@field(f, "t" ++ "wo") == f.two);
70 assert(@field(f, "th" ++ "ree") == f.three);
71 assert(@field(Foo, "const" ++ "ant") == Foo.constant);
72 assert(@field(Bar, "O" ++ "ne") == Bar.One);
73 assert(@field(Bar, "T" ++ "wo") == Bar.Two);
74 assert(@field(Bar, "Th" ++ "ree") == Bar.Three);
75 assert(@field(Bar, "F" ++ "our") == Bar.Four);
76 assert(@field(reflection, "dum" ++ "my")(true, 1, 2) == dummy(true, 1, 2));
77 @field(f, "o" ++ "ne") = 4;
78 assert(f.one == 4);
79}
80
5981const Foo = struct {
82 const constant = 52;
83
6084 one: i32,
6185 two: bool,
6286 three: void,