authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-19 23:23:24-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-19 23:23:24-07:00
loge315120b79f98163dd6413e62684d6ad148295ee
treeabc748fa6b802d4007741ba1ef0fbf1fef1ef152
parent693dbeeef2a35737cec893b50a4fed11b248dd6a

AstGen: implement array initialization expressions


5 files changed, 401 insertions(+), 120 deletions(-)

lib/std/zig/render.zig-1
......@@ -1590,7 +1590,6 @@ fn renderStructInit(
15901590 return renderToken(ais, tree, rbrace, space);
15911591}
15921592
1593// TODO: handle comments between elements
15941593fn renderArrayInit(
15951594 gpa: *Allocator,
15961595 ais: *Ais,
src/AstGen.zig+218-28
......@@ -822,15 +822,20 @@ pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inn
822822 .@"errdefer" => return astgen.failNode(node, "TODO implement astgen.expr for .errdefer", .{}),
823823 .@"try" => return astgen.failNode(node, "TODO implement astgen.expr for .Try", .{}),
824824
825 .array_init_one,
826 .array_init_one_comma,
827 .array_init_dot_two,
828 .array_init_dot_two_comma,
825 .array_init_one, .array_init_one_comma => {
826 var elements: [1]ast.Node.Index = undefined;
827 return arrayInitExpr(gz, scope, rl, node, tree.arrayInitOne(&elements, node));
828 },
829 .array_init_dot_two, .array_init_dot_two_comma => {
830 var elements: [2]ast.Node.Index = undefined;
831 return arrayInitExpr(gz, scope, rl, node, tree.arrayInitDotTwo(&elements, node));
832 },
829833 .array_init_dot,
830834 .array_init_dot_comma,
835 => return arrayInitExpr(gz, scope, rl, node, tree.arrayInitDot(node)),
831836 .array_init,
832837 .array_init_comma,
833 => return astgen.failNode(node, "TODO implement astgen.expr for array literals", .{}),
838 => return arrayInitExpr(gz, scope, rl, node, tree.arrayInit(node)),
834839
835840 .struct_init_one, .struct_init_one_comma => {
836841 var fields: [1]ast.Node.Index = undefined;
......@@ -856,6 +861,182 @@ pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inn
856861 }
857862}
858863
864pub fn arrayInitExpr(
865 gz: *GenZir,
866 scope: *Scope,
867 rl: ResultLoc,
868 node: ast.Node.Index,
869 array_init: ast.full.ArrayInit,
870) InnerError!Zir.Inst.Ref {
871 const astgen = gz.astgen;
872 const tree = &astgen.file.tree;
873 const gpa = astgen.gpa;
874 const node_tags = tree.nodes.items(.tag);
875 const main_tokens = tree.nodes.items(.main_token);
876
877 assert(array_init.ast.elements.len != 0); // Otherwise it would be struct init.
878
879 const types: struct {
880 array: Zir.Inst.Ref,
881 elem: Zir.Inst.Ref,
882 } = inst: {
883 if (array_init.ast.type_expr == 0) break :inst .{
884 .array = .none,
885 .elem = .none,
886 };
887
888 infer: {
889 const array_type: ast.full.ArrayType = switch (node_tags[array_init.ast.type_expr]) {
890 .array_type => tree.arrayType(array_init.ast.type_expr),
891 .array_type_sentinel => tree.arrayTypeSentinel(array_init.ast.type_expr),
892 else => break :infer,
893 };
894 // This intentionally does not support `@"_"` syntax.
895 if (node_tags[array_type.ast.elem_count] == .identifier and
896 mem.eql(u8, tree.tokenSlice(main_tokens[array_type.ast.elem_count]), "_"))
897 {
898 const tag: Zir.Inst.Tag = switch (node_tags[array_init.ast.type_expr]) {
899 .array_type => .array_type,
900 .array_type_sentinel => .array_type_sentinel,
901 else => unreachable,
902 };
903 const len_inst = try gz.addInt(array_init.ast.elements.len);
904 const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type);
905 const array_type_inst = try gz.addBin(tag, len_inst, elem_type);
906 break :inst .{
907 .array = array_type_inst,
908 .elem = elem_type,
909 };
910 }
911 }
912 const array_type_inst = try typeExpr(gz, scope, array_init.ast.type_expr);
913 const elem_type = try gz.addUnNode(.elem_type, array_type_inst, array_init.ast.type_expr);
914 break :inst .{
915 .array = array_type_inst,
916 .elem = elem_type,
917 };
918 };
919
920 switch (rl) {
921 .discard => {
922 for (array_init.ast.elements) |elem_init| {
923 _ = try expr(gz, scope, .discard, elem_init);
924 }
925 return Zir.Inst.Ref.void_value;
926 },
927 .ref => {
928 if (types.array != .none) {
929 return arrayInitExprRlTy(gz, scope, rl, node, array_init.ast.elements, types.array, types.elem, .array_init_ref);
930 } else {
931 return arrayInitExprRlNone(gz, scope, rl, node, array_init.ast.elements, .array_init_anon_ref);
932 }
933 },
934 .none, .none_or_ref => {
935 if (types.array != .none) {
936 return arrayInitExprRlTy(gz, scope, rl, node, array_init.ast.elements, types.array, types.elem, .array_init);
937 } else {
938 return arrayInitExprRlNone(gz, scope, rl, node, array_init.ast.elements, .array_init_anon);
939 }
940 },
941 .ty => |ty_inst| {
942 if (types.array != .none) {
943 const result = try arrayInitExprRlTy(gz, scope, rl, node, array_init.ast.elements, types.array, types.elem, .array_init);
944 return rvalue(gz, scope, rl, result, node);
945 } else {
946 const elem_type = try gz.addUnNode(.elem_type, ty_inst, node);
947 return arrayInitExprRlTy(gz, scope, rl, node, array_init.ast.elements, ty_inst, elem_type, .array_init);
948 }
949 },
950 .ptr, .inferred_ptr => |ptr_inst| {
951 return arrayInitExprRlPtr(gz, scope, rl, node, array_init.ast.elements, ptr_inst);
952 },
953 .block_ptr => |block_gz| {
954 return arrayInitExprRlPtr(gz, scope, rl, node, array_init.ast.elements, block_gz.rl_ptr);
955 },
956 }
957}
958
959pub fn arrayInitExprRlNone(
960 gz: *GenZir,
961 scope: *Scope,
962 rl: ResultLoc,
963 node: ast.Node.Index,
964 elements: []const ast.Node.Index,
965 tag: Zir.Inst.Tag,
966) InnerError!Zir.Inst.Ref {
967 const astgen = gz.astgen;
968 const gpa = astgen.gpa;
969 const elem_list = try gpa.alloc(Zir.Inst.Ref, elements.len);
970 defer gpa.free(elem_list);
971
972 for (elements) |elem_init, i| {
973 elem_list[i] = try expr(gz, scope, .none, elem_init);
974 }
975 const init_inst = try gz.addPlNode(tag, node, Zir.Inst.MultiOp{
976 .operands_len = @intCast(u32, elem_list.len),
977 });
978 try astgen.appendRefs(elem_list);
979 return init_inst;
980}
981
982pub fn arrayInitExprRlTy(
983 gz: *GenZir,
984 scope: *Scope,
985 rl: ResultLoc,
986 node: ast.Node.Index,
987 elements: []const ast.Node.Index,
988 array_ty_inst: Zir.Inst.Ref,
989 elem_ty_inst: Zir.Inst.Ref,
990 tag: Zir.Inst.Tag,
991) InnerError!Zir.Inst.Ref {
992 const astgen = gz.astgen;
993 const gpa = astgen.gpa;
994
995 const elem_list = try gpa.alloc(Zir.Inst.Ref, elements.len);
996 defer gpa.free(elem_list);
997
998 const elem_rl: ResultLoc = .{ .ty = elem_ty_inst };
999
1000 for (elements) |elem_init, i| {
1001 elem_list[i] = try expr(gz, scope, elem_rl, elem_init);
1002 }
1003 const init_inst = try gz.addPlNode(tag, node, Zir.Inst.MultiOp{
1004 .operands_len = @intCast(u32, elem_list.len),
1005 });
1006 try astgen.appendRefs(elem_list);
1007 return init_inst;
1008}
1009
1010pub fn arrayInitExprRlPtr(
1011 gz: *GenZir,
1012 scope: *Scope,
1013 rl: ResultLoc,
1014 node: ast.Node.Index,
1015 elements: []const ast.Node.Index,
1016 result_ptr: Zir.Inst.Ref,
1017) InnerError!Zir.Inst.Ref {
1018 const astgen = gz.astgen;
1019 const gpa = astgen.gpa;
1020
1021 const elem_ptr_list = try gpa.alloc(Zir.Inst.Index, elements.len);
1022 defer gpa.free(elem_ptr_list);
1023
1024 for (elements) |elem_init, i| {
1025 const index_inst = try gz.addInt(i);
1026 const elem_ptr = try gz.addPlNode(.elem_ptr_node, elem_init, Zir.Inst.Bin{
1027 .lhs = result_ptr,
1028 .rhs = index_inst,
1029 });
1030 elem_ptr_list[i] = gz.refToIndex(elem_ptr).?;
1031 _ = try expr(gz, scope, .{ .ptr = elem_ptr }, elem_init);
1032 }
1033 _ = try gz.addPlNode(.validate_array_init_ptr, node, Zir.Inst.Block{
1034 .body_len = @intCast(u32, elem_ptr_list.len),
1035 });
1036 try astgen.extra.appendSlice(gpa, elem_ptr_list);
1037 return .void_value;
1038}
1039
8591040pub fn structInitExpr(
8601041 gz: *GenZir,
8611042 scope: *Scope,
......@@ -911,7 +1092,14 @@ pub fn structInitExpr(
9111092 return init_inst;
9121093 },
9131094 .ref => unreachable, // struct literal not valid as l-value
914 .ty => |ty_inst| return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst),
1095 .ty => |ty_inst| {
1096 if (struct_init.ast.type_expr == 0) {
1097 return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst);
1098 }
1099 const inner_ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
1100 const result = try structInitExprRlTy(gz, scope, rl, node, struct_init, inner_ty_inst);
1101 return rvalue(gz, scope, rl, result, node);
1102 },
9151103 .ptr, .inferred_ptr => |ptr_inst| return structInitExprRlPtr(gz, scope, rl, node, struct_init, ptr_inst),
9161104 .block_ptr => |block_gz| return structInitExprRlPtr(gz, scope, rl, node, struct_init, block_gz.rl_ptr),
9171105 }
......@@ -942,11 +1130,11 @@ pub fn structInitExprRlPtr(
9421130 field_ptr_list[i] = gz.refToIndex(field_ptr).?;
9431131 _ = try expr(gz, scope, .{ .ptr = field_ptr }, field_init);
9441132 }
945 const validate_inst = try gz.addPlNode(.validate_struct_init_ptr, node, Zir.Inst.Block{
1133 _ = try gz.addPlNode(.validate_struct_init_ptr, node, Zir.Inst.Block{
9461134 .body_len = @intCast(u32, field_ptr_list.len),
9471135 });
9481136 try astgen.extra.appendSlice(gpa, field_ptr_list);
949 return validate_inst;
1137 return .void_value;
9501138}
9511139
9521140pub fn structInitExprRlTy(
......@@ -1336,6 +1524,7 @@ fn blockExprStmts(
13361524 .array_mul,
13371525 .array_type,
13381526 .array_type_sentinel,
1527 .elem_type,
13391528 .indexable_ptr_len,
13401529 .as,
13411530 .as_node,
......@@ -1393,8 +1582,6 @@ fn blockExprStmts(
13931582 .param_type,
13941583 .ptrtoint,
13951584 .ref,
1396 .ret_ptr,
1397 .ret_type,
13981585 .shl,
13991586 .shr,
14001587 .str,
......@@ -1453,6 +1640,10 @@ fn blockExprStmts(
14531640 .struct_init_empty,
14541641 .struct_init,
14551642 .struct_init_anon,
1643 .array_init,
1644 .array_init_anon,
1645 .array_init_ref,
1646 .array_init_anon_ref,
14561647 .union_init_ptr,
14571648 .field_type,
14581649 .field_type_ref,
......@@ -1469,18 +1660,12 @@ fn blockExprStmts(
14691660 .type_info,
14701661 .size_of,
14711662 .bit_size_of,
1472 .this,
1473 .ret_addr,
1474 .builtin_src,
14751663 .add_with_overflow,
14761664 .sub_with_overflow,
14771665 .mul_with_overflow,
14781666 .shl_with_overflow,
14791667 .log2_int_type,
14801668 .typeof_log2_int_type,
1481 .error_return_trace,
1482 .frame,
1483 .frame_address,
14841669 .ptr_to_int,
14851670 .align_of,
14861671 .bool_to_int,
......@@ -1575,6 +1760,7 @@ fn blockExprStmts(
15751760 .repeat,
15761761 .repeat_inline,
15771762 .validate_struct_init_ptr,
1763 .validate_array_init_ptr,
15781764 .panic,
15791765 .set_align_stack,
15801766 .set_cold,
......@@ -2572,13 +2758,17 @@ fn structDeclInner(
25722758
25732759 field_index += 1;
25742760 }
2575 if (field_index != 0) {
2761 {
25762762 const empty_slot_count = 16 - (field_index % 16);
2577 cur_bit_bag >>= @intCast(u5, empty_slot_count * 2);
2763 if (empty_slot_count < 16) {
2764 cur_bit_bag >>= @intCast(u5, empty_slot_count * 2);
2765 }
25782766 }
2579 if (wip_decls.decl_index != 0) {
2767 {
25802768 const empty_slot_count = 16 - (wip_decls.decl_index % 16);
2581 wip_decls.cur_bit_bag >>= @intCast(u5, empty_slot_count * 2);
2769 if (empty_slot_count < 16) {
2770 wip_decls.cur_bit_bag >>= @intCast(u5, empty_slot_count * 2);
2771 }
25822772 }
25832773
25842774 const decl_inst = try gz.addBlock(tag, node);
......@@ -4609,9 +4799,9 @@ fn ret(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref
46094799 const operand_node = node_datas[node].lhs;
46104800 const operand: Zir.Inst.Ref = if (operand_node != 0) operand: {
46114801 const rl: ResultLoc = if (nodeMayNeedMemoryLocation(tree, operand_node)) .{
4612 .ptr = try gz.addNode(.ret_ptr, node),
4802 .ptr = try gz.addNodeExtended(.ret_ptr, node),
46134803 } else .{
4614 .ty = try gz.addNode(.ret_type, node),
4804 .ty = try gz.addNodeExtended(.ret_type, node),
46154805 };
46164806 break :operand try expr(gz, scope, rl, operand_node);
46174807 } else .void_value;
......@@ -5203,12 +5393,12 @@ fn builtinCall(
52035393 .breakpoint => return simpleNoOpVoid(gz, scope, rl, node, .breakpoint),
52045394 .fence => return simpleNoOpVoid(gz, scope, rl, node, .fence),
52055395
5206 .This => return rvalue(gz, scope, rl, try gz.addNode(.this, node), node),
5207 .return_address => return rvalue(gz, scope, rl, try gz.addNode(.ret_addr, node), node),
5208 .src => return rvalue(gz, scope, rl, try gz.addNode(.builtin_src, node), node),
5209 .error_return_trace => return rvalue(gz, scope, rl, try gz.addNode(.error_return_trace, node), node),
5210 .frame => return rvalue(gz, scope, rl, try gz.addNode(.frame, node), node),
5211 .frame_address => return rvalue(gz, scope, rl, try gz.addNode(.frame_address, node), node),
5396 .This => return rvalue(gz, scope, rl, try gz.addNodeExtended(.this, node), node),
5397 .return_address => return rvalue(gz, scope, rl, try gz.addNodeExtended(.ret_addr, node), node),
5398 .src => return rvalue(gz, scope, rl, try gz.addNodeExtended(.builtin_src, node), node),
5399 .error_return_trace => return rvalue(gz, scope, rl, try gz.addNodeExtended(.error_return_trace, node), node),
5400 .frame => return rvalue(gz, scope, rl, try gz.addNodeExtended(.frame, node), node),
5401 .frame_address => return rvalue(gz, scope, rl, try gz.addNodeExtended(.frame_address, node), node),
52125402
52135403 .type_info => return simpleUnOpType(gz, scope, rl, node, params[0], .type_info),
52145404 .size_of => return simpleUnOpType(gz, scope, rl, node, params[0], .size_of),
src/Module.zig+17
......@@ -1622,6 +1622,22 @@ pub const Scope = struct {
16221622 });
16231623 }
16241624
1625 pub fn addNodeExtended(
1626 gz: *GenZir,
1627 opcode: Zir.Inst.Extended,
1628 /// Absolute node index. This function does the conversion to offset from Decl.
1629 src_node: ast.Node.Index,
1630 ) !Zir.Inst.Ref {
1631 return gz.add(.{
1632 .tag = .extended,
1633 .data = .{ .extended = .{
1634 .opcode = opcode,
1635 .small = undefined,
1636 .operand = @bitCast(u32, gz.nodeIndexToRelative(src_node)),
1637 } },
1638 });
1639 }
1640
16251641 /// Asserts that `str` is 8 or fewer bytes.
16261642 pub fn addSmallStr(
16271643 gz: *GenZir,
......@@ -2583,6 +2599,7 @@ pub fn astGenFile(mod: *Module, file: *Scope.File, prog_node: *std.Progress.Node
25832599 return error.AnalysisFail;
25842600 }
25852601
2602 log.debug("AstGen success: {s}", .{file.sub_file_path});
25862603 file.status = .success;
25872604}
25882605
src/Sema.zig+105-50
......@@ -175,6 +175,7 @@ pub fn analyzeBody(
175175 .elem_ptr_node => try sema.zirElemPtrNode(block, inst),
176176 .elem_val => try sema.zirElemVal(block, inst),
177177 .elem_val_node => try sema.zirElemValNode(block, inst),
178 .elem_type => try sema.zirElemType(block, inst),
178179 .enum_literal => try sema.zirEnumLiteral(block, inst),
179180 .enum_literal_small => try sema.zirEnumLiteralSmall(block, inst),
180181 .enum_to_int => try sema.zirEnumToInt(block, inst),
......@@ -223,8 +224,6 @@ pub fn analyzeBody(
223224 .ptr_type_simple => try sema.zirPtrTypeSimple(block, inst),
224225 .ptrtoint => try sema.zirPtrtoint(block, inst),
225226 .ref => try sema.zirRef(block, inst),
226 .ret_ptr => try sema.zirRetPtr(block, inst),
227 .ret_type => try sema.zirRetType(block, inst),
228227 .shl => try sema.zirShl(block, inst),
229228 .shr => try sema.zirShr(block, inst),
230229 .slice_end => try sema.zirSliceEnd(block, inst),
......@@ -252,9 +251,6 @@ pub fn analyzeBody(
252251 .type_info => try sema.zirTypeInfo(block, inst),
253252 .size_of => try sema.zirSizeOf(block, inst),
254253 .bit_size_of => try sema.zirBitSizeOf(block, inst),
255 .this => try sema.zirThis(block, inst),
256 .ret_addr => try sema.zirRetAddr(block, inst),
257 .builtin_src => try sema.zirBuiltinSrc(block, inst),
258254 .typeof => try sema.zirTypeof(block, inst),
259255 .typeof_elem => try sema.zirTypeofElem(block, inst),
260256 .typeof_peer => try sema.zirTypeofPeer(block, inst),
......@@ -264,12 +260,13 @@ pub fn analyzeBody(
264260 .struct_init_empty => try sema.zirStructInitEmpty(block, inst),
265261 .struct_init => try sema.zirStructInit(block, inst),
266262 .struct_init_anon => try sema.zirStructInitAnon(block, inst),
263 .array_init => try sema.zirArrayInit(block, inst, false),
264 .array_init_anon => try sema.zirArrayInitAnon(block, inst, false),
265 .array_init_ref => try sema.zirArrayInit(block, inst, true),
266 .array_init_anon_ref => try sema.zirArrayInitAnon(block, inst, true),
267267 .union_init_ptr => try sema.zirUnionInitPtr(block, inst),
268268 .field_type => try sema.zirFieldType(block, inst),
269269 .field_type_ref => try sema.zirFieldTypeRef(block, inst),
270 .error_return_trace => try sema.zirErrorReturnTrace(block, inst),
271 .frame => try sema.zirFrame(block, inst),
272 .frame_address => try sema.zirFrameAddress(block, inst),
273270 .ptr_to_int => try sema.zirPtrToInt(block, inst),
274271 .align_of => try sema.zirAlignOf(block, inst),
275272 .bool_to_int => try sema.zirBoolToInt(block, inst),
......@@ -435,6 +432,10 @@ pub fn analyzeBody(
435432 try sema.zirValidateStructInitPtr(block, inst);
436433 continue;
437434 },
435 .validate_array_init_ptr => {
436 try sema.zirValidateArrayInitPtr(block, inst);
437 continue;
438 },
438439 .@"export" => {
439440 try sema.zirExport(block, inst);
440441 continue;
......@@ -499,6 +500,28 @@ pub fn analyzeBody(
499500 }
500501}
501502
503fn zirExtended(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
504 const extended = sema.code.instructions.items(.data)[inst].extended;
505 switch (extended.opcode) {
506 // zig fmt: off
507 .func => return sema.zirFuncExtended( block, extended),
508 .ret_ptr => return sema.zirRetPtr( block, extended),
509 .ret_type => return sema.zirRetType( block, extended),
510 .this => return sema.zirThis( block, extended),
511 .ret_addr => return sema.zirRetAddr( block, extended),
512 .builtin_src => return sema.zirBuiltinSrc( block, extended),
513 .error_return_trace => return sema.zirErrorReturnTrace(block, extended),
514 .frame => return sema.zirFrame( block, extended),
515 .frame_address => return sema.zirFrameAddress( block, extended),
516 .c_undef => return sema.zirCUndef( block, extended),
517 .c_include => return sema.zirCInclude( block, extended),
518 .c_define => return sema.zirCDefine( block, extended),
519 .wasm_memory_size => return sema.zirWasmMemorySize( block, extended),
520 .wasm_memory_grow => return sema.zirWasmMemoryGrow( block, extended),
521 // zig fmt: on
522 }
523}
524
502525/// TODO when we rework TZIR memory layout, this function will no longer have a possible error.
503526pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) error{OutOfMemory}!*ir.Inst {
504527 var i: usize = @enumToInt(zir_ref);
......@@ -990,11 +1013,15 @@ fn zirErrorSetDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner
9901013 return sema.mod.fail(&block.base, sema.src, "TODO implement zirErrorSetDecl", .{});
9911014}
9921015
993fn zirRetPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
1016fn zirRetPtr(
1017 sema: *Sema,
1018 block: *Scope.Block,
1019 extended: Zir.Inst.Extended.InstData,
1020) InnerError!*Inst {
9941021 const tracy = trace(@src());
9951022 defer tracy.end();
9961023
997 const src: LazySrcLoc = .unneeded;
1024 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
9981025 try sema.requireFunctionBlock(block, src);
9991026 const fn_ty = sema.func.?.owner_decl.typed_value.most_recent.typed_value.ty;
10001027 const ret_type = fn_ty.fnReturnType();
......@@ -1011,11 +1038,15 @@ fn zirRef(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*In
10111038 return sema.analyzeRef(block, inst_data.src(), operand);
10121039}
10131040
1014fn zirRetType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
1041fn zirRetType(
1042 sema: *Sema,
1043 block: *Scope.Block,
1044 extended: Zir.Inst.Extended.InstData,
1045) InnerError!*Inst {
10151046 const tracy = trace(@src());
10161047 defer tracy.end();
10171048
1018 const src: LazySrcLoc = .unneeded;
1049 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
10191050 try sema.requireFunctionBlock(block, src);
10201051 const fn_ty = sema.func.?.owner_decl.typed_value.most_recent.typed_value.ty;
10211052 const ret_type = fn_ty.fnReturnType();
......@@ -1247,6 +1278,12 @@ fn zirValidateStructInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Ind
12471278 }
12481279}
12491280
1281fn zirValidateArrayInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!void {
1282 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1283 const src = inst_data.src();
1284 return sema.mod.fail(&block.base, src, "TODO implement Sema.zirValidateArrayInitPtr", .{});
1285}
1286
12501287fn failWithBadFieldAccess(
12511288 sema: *Sema,
12521289 block: *Scope.Block,
......@@ -2064,6 +2101,14 @@ fn zirOptionalTypeFromPtrElem(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.I
20642101 return sema.mod.constType(sema.arena, inst_data.src(), opt_ty);
20652102}
20662103
2104fn zirElemType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
2105 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
2106 const src = inst_data.src();
2107 const array_type = try sema.resolveType(block, src, inst_data.operand);
2108 const elem_type = array_type.elemType();
2109 return sema.mod.constType(sema.arena, src, elem_type);
2110}
2111
20672112fn zirArrayType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
20682113 const tracy = trace(@src());
20692114 defer tracy.end();
......@@ -4512,21 +4557,30 @@ fn zirBitSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr
45124557 return sema.mod.constIntUnsigned(sema.arena, src, Type.initTag(.comptime_int), bit_size);
45134558}
45144559
4515fn zirThis(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
4516 const src_node = sema.code.instructions.items(.data)[inst].node;
4517 const src: LazySrcLoc = .{ .node_offset = src_node };
4560fn zirThis(
4561 sema: *Sema,
4562 block: *Scope.Block,
4563 extended: Zir.Inst.Extended.InstData,
4564) InnerError!*Inst {
4565 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
45184566 return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirThis", .{});
45194567}
45204568
4521fn zirRetAddr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
4522 const src_node = sema.code.instructions.items(.data)[inst].node;
4523 const src: LazySrcLoc = .{ .node_offset = src_node };
4569fn zirRetAddr(
4570 sema: *Sema,
4571 block: *Scope.Block,
4572 extended: Zir.Inst.Extended.InstData,
4573) InnerError!*Inst {
4574 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
45244575 return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirRetAddr", .{});
45254576}
45264577
4527fn zirBuiltinSrc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
4528 const src_node = sema.code.instructions.items(.data)[inst].node;
4529 const src: LazySrcLoc = .{ .node_offset = src_node };
4578fn zirBuiltinSrc(
4579 sema: *Sema,
4580 block: *Scope.Block,
4581 extended: Zir.Inst.Extended.InstData,
4582) InnerError!*Inst {
4583 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
45304584 return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirBuiltinSrc", .{});
45314585}
45324586
......@@ -4983,6 +5037,18 @@ fn zirStructInitAnon(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inn
49835037 return sema.mod.fail(&block.base, src, "TODO: Sema.zirStructInitAnon", .{});
49845038}
49855039
5040fn zirArrayInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: bool) InnerError!*Inst {
5041 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
5042 const src = inst_data.src();
5043 return sema.mod.fail(&block.base, src, "TODO: Sema.zirArrayInit", .{});
5044}
5045
5046fn zirArrayInitAnon(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: bool) InnerError!*Inst {
5047 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
5048 const src = inst_data.src();
5049 return sema.mod.fail(&block.base, src, "TODO: Sema.zirArrayInitAnon", .{});
5050}
5051
49865052fn zirFieldTypeRef(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
49875053 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
49885054 const src = inst_data.src();
......@@ -4995,21 +5061,30 @@ fn zirFieldType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr
49955061 return sema.mod.fail(&block.base, src, "TODO: Sema.zirFieldType", .{});
49965062}
49975063
4998fn zirErrorReturnTrace(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
4999 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
5000 const src = inst_data.src();
5064fn zirErrorReturnTrace(
5065 sema: *Sema,
5066 block: *Scope.Block,
5067 extended: Zir.Inst.Extended.InstData,
5068) InnerError!*Inst {
5069 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
50015070 return sema.mod.fail(&block.base, src, "TODO: Sema.zirErrorReturnTrace", .{});
50025071}
50035072
5004fn zirFrame(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
5005 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
5006 const src = inst_data.src();
5073fn zirFrame(
5074 sema: *Sema,
5075 block: *Scope.Block,
5076 extended: Zir.Inst.Extended.InstData,
5077) InnerError!*Inst {
5078 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
50075079 return sema.mod.fail(&block.base, src, "TODO: Sema.zirFrame", .{});
50085080}
50095081
5010fn zirFrameAddress(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
5011 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
5012 const src = inst_data.src();
5082fn zirFrameAddress(
5083 sema: *Sema,
5084 block: *Scope.Block,
5085 extended: Zir.Inst.Extended.InstData,
5086) InnerError!*Inst {
5087 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
50135088 return sema.mod.fail(&block.base, src, "TODO: Sema.zirFrameAddress", .{});
50145089}
50155090
......@@ -5295,24 +5370,9 @@ fn zirBuiltinAsyncCall(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) I
52955370 return sema.mod.fail(&block.base, src, "TODO: Sema.zirBuiltinAsyncCall", .{});
52965371}
52975372
5298fn zirExtended(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
5299 const extended = sema.code.instructions.items(.data)[inst].extended;
5300 switch (extended.opcode) {
5301 // zig fmt: off
5302 .func => return sema.zirFuncExtended( block, inst, extended),
5303 .c_undef => return sema.zirCUndef( block, inst, extended),
5304 .c_include => return sema.zirCInclude( block, inst, extended),
5305 .c_define => return sema.zirCDefine( block, inst, extended),
5306 .wasm_memory_size => return sema.zirWasmMemorySize(block, inst, extended),
5307 .wasm_memory_grow => return sema.zirWasmMemoryGrow(block, inst, extended),
5308 // zig fmt: on
5309 }
5310}
5311
53125373fn zirFuncExtended(
53135374 sema: *Sema,
53145375 block: *Scope.Block,
5315 inst: Zir.Inst.Index,
53165376 extended: Zir.Inst.Extended.InstData,
53175377) InnerError!*Inst {
53185378 const tracy = trace(@src());
......@@ -5364,7 +5424,6 @@ fn zirFuncExtended(
53645424fn zirCUndef(
53655425 sema: *Sema,
53665426 block: *Scope.Block,
5367 inst: Zir.Inst.Index,
53685427 extended: Zir.Inst.Extended.InstData,
53695428) InnerError!*Inst {
53705429 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
......@@ -5375,7 +5434,6 @@ fn zirCUndef(
53755434fn zirCInclude(
53765435 sema: *Sema,
53775436 block: *Scope.Block,
5378 inst: Zir.Inst.Index,
53795437 extended: Zir.Inst.Extended.InstData,
53805438) InnerError!*Inst {
53815439 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
......@@ -5386,7 +5444,6 @@ fn zirCInclude(
53865444fn zirCDefine(
53875445 sema: *Sema,
53885446 block: *Scope.Block,
5389 inst: Zir.Inst.Index,
53905447 extended: Zir.Inst.Extended.InstData,
53915448) InnerError!*Inst {
53925449 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
......@@ -5397,7 +5454,6 @@ fn zirCDefine(
53975454fn zirWasmMemorySize(
53985455 sema: *Sema,
53995456 block: *Scope.Block,
5400 inst: Zir.Inst.Index,
54015457 extended: Zir.Inst.Extended.InstData,
54025458) InnerError!*Inst {
54035459 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
......@@ -5408,7 +5464,6 @@ fn zirWasmMemorySize(
54085464fn zirWasmMemoryGrow(
54095465 sema: *Sema,
54105466 block: *Scope.Block,
5411 inst: Zir.Inst.Index,
54125467 extended: Zir.Inst.Extended.InstData,
54135468) InnerError!*Inst {
54145469 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
src/Zir.zig+61-41
......@@ -169,6 +169,9 @@ pub const Inst = struct {
169169 /// `[N:S]T` syntax. No source location provided.
170170 /// Uses the `array_type_sentinel` field.
171171 array_type_sentinel,
172 /// Given an array type, returns the element type.
173 /// Uses the `un_node` union field.
174 elem_type,
172175 /// Given a pointer to an indexable object, returns the len property. This is
173176 /// used by for loops. This instruction also emits a for-loop specific compile
174177 /// error if the indexable object is not indexable.
......@@ -457,12 +460,6 @@ pub const Inst = struct {
457460 /// instruction.
458461 /// Uses the `un_tok` union field.
459462 ref,
460 /// Obtains a pointer to the return value.
461 /// Uses the `node` union field.
462 ret_ptr,
463 /// Obtains the return type of the in-scope function.
464 /// Uses the `node` union field.
465 ret_type,
466463 /// Sends control flow back to the function's callee.
467464 /// Includes an operand as the return value.
468465 /// Includes an AST node source location.
......@@ -674,6 +671,13 @@ pub const Inst = struct {
674671 /// because it must use one of them to find out the struct type.
675672 /// Uses the `pl_node` field. Payload is `Block`.
676673 validate_struct_init_ptr,
674 /// Given a set of `elem_ptr_node` instructions, assumes they are all part of an
675 /// array initialization expression, and emits a compile error if the number of
676 /// elements does not match the array type.
677 /// This instruction asserts that there is at least one elem_ptr_node instruction,
678 /// because it must use one of them to find out the array type.
679 /// Uses the `pl_node` field. Payload is `Block`.
680 validate_array_init_ptr,
677681 /// A struct literal with a specified type, with no fields.
678682 /// Uses the `un_node` field.
679683 struct_init_empty,
......@@ -690,6 +694,18 @@ pub const Inst = struct {
690694 /// Struct initialization without a type.
691695 /// Uses the `pl_node` field. Payload is `StructInitAnon`.
692696 struct_init_anon,
697 /// Array initialization syntax.
698 /// Uses the `pl_node` field. Payload is `MultiOp`.
699 array_init,
700 /// Anonymous array initialization syntax.
701 /// Uses the `pl_node` field. Payload is `MultiOp`.
702 array_init_anon,
703 /// Array initialization syntax, make the result a pointer.
704 /// Uses the `pl_node` field. Payload is `MultiOp`.
705 array_init_ref,
706 /// Anonymous array initialization syntax, make the result a pointer.
707 /// Uses the `pl_node` field. Payload is `MultiOp`.
708 array_init_anon_ref,
693709 /// Given a pointer to a union and a comptime known field name, activates that field
694710 /// and returns a pointer to it.
695711 /// Uses the `pl_node` field. Payload is `UnionInitPtr`.
......@@ -700,14 +716,8 @@ pub const Inst = struct {
700716 size_of,
701717 /// Implements the `@bitSizeOf` builtin. Uses `un_node`.
702718 bit_size_of,
703 /// Implements the `@This` builtin. Uses `node`.
704 this,
705 /// Implements the `@fence` builtin. Uses `un_node`.
719 /// Implements the `@fence` builtin. Uses `node`.
706720 fence,
707 /// Implements the `@returnAddress` builtin. Uses `un_node`.
708 ret_addr,
709 /// Implements the `@src` builtin. Uses `un_node`.
710 builtin_src,
711721 /// Implements the `@addWithOverflow` builtin. Uses `pl_node` with `OverflowArithmetic`.
712722 add_with_overflow,
713723 /// Implements the `@subWithOverflow` builtin. Uses `pl_node` with `OverflowArithmetic`.
......@@ -717,16 +727,6 @@ pub const Inst = struct {
717727 /// Implements the `@shlWithOverflow` builtin. Uses `pl_node` with `OverflowArithmetic`.
718728 shl_with_overflow,
719729
720 /// Implements the `@errorReturnTrace` builtin.
721 /// Uses the `un_node` field.
722 error_return_trace,
723 /// Implements the `@frame` builtin.
724 /// Uses the `un_node` field.
725 frame,
726 /// Implements the `@frameAddress` builtin.
727 /// Uses the `un_node` field.
728 frame_address,
729
730730 /// Implement builtin `@ptrToInt`. Uses `un_node`.
731731 ptr_to_int,
732732 /// Implement builtin `@errToInt`. Uses `un_node`.
......@@ -951,6 +951,7 @@ pub const Inst = struct {
951951 .array_mul,
952952 .array_type,
953953 .array_type_sentinel,
954 .elem_type,
954955 .indexable_ptr_len,
955956 .as,
956957 .as_node,
......@@ -970,6 +971,7 @@ pub const Inst = struct {
970971 .bool_and,
971972 .bool_or,
972973 .breakpoint,
974 .fence,
973975 .call,
974976 .call_chkused,
975977 .call_compile_time,
......@@ -1026,8 +1028,6 @@ pub const Inst = struct {
10261028 .param_type,
10271029 .ptrtoint,
10281030 .ref,
1029 .ret_ptr,
1030 .ret_type,
10311031 .shl,
10321032 .shr,
10331033 .store,
......@@ -1094,9 +1094,14 @@ pub const Inst = struct {
10941094 .switch_block_ref_under,
10951095 .switch_block_ref_under_multi,
10961096 .validate_struct_init_ptr,
1097 .validate_array_init_ptr,
10971098 .struct_init_empty,
10981099 .struct_init,
10991100 .struct_init_anon,
1101 .array_init,
1102 .array_init_anon,
1103 .array_init_ref,
1104 .array_init_anon_ref,
11001105 .union_init_ptr,
11011106 .field_type,
11021107 .field_type_ref,
......@@ -1105,17 +1110,10 @@ pub const Inst = struct {
11051110 .type_info,
11061111 .size_of,
11071112 .bit_size_of,
1108 .this,
1109 .fence,
1110 .ret_addr,
1111 .builtin_src,
11121113 .add_with_overflow,
11131114 .sub_with_overflow,
11141115 .mul_with_overflow,
11151116 .shl_with_overflow,
1116 .error_return_trace,
1117 .frame,
1118 .frame_address,
11191117 .ptr_to_int,
11201118 .align_of,
11211119 .bool_to_int,
......@@ -1211,6 +1209,30 @@ pub const Inst = struct {
12111209 /// `operand` is payload index to `ExtendedFunc`.
12121210 /// `small` is `ExtendedFunc.Small`.
12131211 func,
1212 /// Obtains a pointer to the return value.
1213 /// `operand` is `src_node: i32`.
1214 ret_ptr,
1215 /// Obtains the return type of the in-scope function.
1216 /// `operand` is `src_node: i32`.
1217 ret_type,
1218 /// Implements the `@This` builtin.
1219 /// `operand` is `src_node: i32`.
1220 this,
1221 /// Implements the `@returnAddress` builtin.
1222 /// `operand` is `src_node: i32`.
1223 ret_addr,
1224 /// Implements the `@src` builtin.
1225 /// `operand` is `src_node: i32`.
1226 builtin_src,
1227 /// Implements the `@errorReturnTrace` builtin.
1228 /// `operand` is `src_node: i32`.
1229 error_return_trace,
1230 /// Implements the `@frame` builtin.
1231 /// `operand` is `src_node: i32`.
1232 frame,
1233 /// Implements the `@frameAddress` builtin.
1234 /// `operand` is `src_node: i32`.
1235 frame_address,
12141236 /// `operand` is payload index to `UnNode`.
12151237 c_undef,
12161238 /// `operand` is payload index to `UnNode`.
......@@ -2281,6 +2303,7 @@ const Writer = struct {
22812303 .pop_count,
22822304 .byte_swap,
22832305 .bit_reverse,
2306 .elem_type,
22842307 => try self.writeUnNode(stream, inst),
22852308
22862309 .ref,
......@@ -2317,6 +2340,10 @@ const Writer = struct {
23172340 .union_decl,
23182341 .struct_init,
23192342 .struct_init_anon,
2343 .array_init,
2344 .array_init_anon,
2345 .array_init_ref,
2346 .array_init_anon_ref,
23202347 .union_init_ptr,
23212348 .field_type,
23222349 .field_type_ref,
......@@ -2409,6 +2436,7 @@ const Writer = struct {
24092436 .block_inline_var,
24102437 .loop,
24112438 .validate_struct_init_ptr,
2439 .validate_array_init_ptr,
24122440 .c_import,
24132441 => try self.writePlNodeBlock(stream, inst),
24142442
......@@ -2450,21 +2478,13 @@ const Writer = struct {
24502478 .as_node => try self.writeAs(stream, inst),
24512479
24522480 .breakpoint,
2481 .fence,
24532482 .opaque_decl,
24542483 .dbg_stmt_node,
2455 .ret_ptr,
2456 .ret_type,
24572484 .repeat,
24582485 .repeat_inline,
24592486 .alloc_inferred,
24602487 .alloc_inferred_mut,
2461 .this,
2462 .fence,
2463 .ret_addr,
2464 .builtin_src,
2465 .error_return_trace,
2466 .frame,
2467 .frame_address,
24682488 => try self.writeNode(stream, inst),
24692489
24702490 .error_value,