authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-08 22:33:40-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-08 22:33:40-07:00
log6e05d53e88e07d6234aaf6e0b86cd52d8c9aea92
treece5cfe10979d9da235a2944b714bfc1eb77ba824
parent91e1414b50beac41b8eee5e3a9f8ef7bdc67fdef

AstGen: implement struct init with ResultLoc.ty


3 files changed, 70 insertions(+), 1 deletions(-)

src/AstGen.zig+27-1
...@@ -823,7 +823,31 @@ pub fn structInitExpr(...@@ -823,7 +823,31 @@ pub fn structInitExpr(
823 .none, .none_or_ref => return mod.failNode(scope, node, "TODO implement structInitExpr none", .{}),823 .none, .none_or_ref => return mod.failNode(scope, node, "TODO implement structInitExpr none", .{}),
824 .ref => unreachable, // struct literal not valid as l-value824 .ref => unreachable, // struct literal not valid as l-value
825 .ty => |ty_inst| {825 .ty => |ty_inst| {
826 return mod.failNode(scope, node, "TODO implement structInitExpr ty", .{});826 const fields_list = try gpa.alloc(zir.Inst.StructInit.Item, struct_init.ast.fields.len);
827 defer gpa.free(fields_list);
828
829 for (struct_init.ast.fields) |field_init, i| {
830 const name_token = tree.firstToken(field_init) - 2;
831 const str_index = try gz.identAsString(name_token);
832
833 const field_ty_inst = try gz.addPlNode(.field_type, field_init, zir.Inst.FieldType{
834 .container_type = ty_inst,
835 .name_start = str_index,
836 });
837 fields_list[i] = .{
838 .field_type = astgen.refToIndex(field_ty_inst).?,
839 .init = try expr(gz, scope, .{ .ty = field_ty_inst }, field_init),
840 };
841 }
842 const init_inst = try gz.addPlNode(.struct_init, node, zir.Inst.StructInit{
843 .fields_len = @intCast(u32, fields_list.len),
844 });
845 try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +
846 fields_list.len * @typeInfo(zir.Inst.StructInit.Item).Struct.fields.len);
847 for (fields_list) |field| {
848 _ = gz.astgen.addExtraAssumeCapacity(field);
849 }
850 return rvalue(gz, scope, rl, init_inst, node);
827 },851 },
828 .ptr => |ptr_inst| {852 .ptr => |ptr_inst| {
829 const field_ptr_list = try gpa.alloc(zir.Inst.Index, struct_init.ast.fields.len);853 const field_ptr_list = try gpa.alloc(zir.Inst.Index, struct_init.ast.fields.len);
...@@ -1321,6 +1345,8 @@ fn blockExprStmts(...@@ -1321,6 +1345,8 @@ fn blockExprStmts(
1321 .switch_capture_else,1345 .switch_capture_else,
1322 .switch_capture_else_ref,1346 .switch_capture_else_ref,
1323 .struct_init_empty,1347 .struct_init_empty,
1348 .struct_init,
1349 .field_type,
1324 .struct_decl,1350 .struct_decl,
1325 .struct_decl_packed,1351 .struct_decl_packed,
1326 .struct_decl_extern,1352 .struct_decl_extern,
src/Sema.zig+14
...@@ -264,6 +264,8 @@ pub fn analyzeBody(...@@ -264,6 +264,8 @@ pub fn analyzeBody(
264 .typeof_peer => try sema.zirTypeofPeer(block, inst),264 .typeof_peer => try sema.zirTypeofPeer(block, inst),
265 .xor => try sema.zirBitwise(block, inst, .xor),265 .xor => try sema.zirBitwise(block, inst, .xor),
266 .struct_init_empty => try sema.zirStructInitEmpty(block, inst),266 .struct_init_empty => try sema.zirStructInitEmpty(block, inst),
267 .struct_init => try sema.zirStructInit(block, inst),
268 .field_type => try sema.zirFieldType(block, inst),
267269
268 .struct_decl => try sema.zirStructDecl(block, inst, .Auto),270 .struct_decl => try sema.zirStructDecl(block, inst, .Auto),
269 .struct_decl_packed => try sema.zirStructDecl(block, inst, .Packed),271 .struct_decl_packed => try sema.zirStructDecl(block, inst, .Packed),
...@@ -4493,6 +4495,18 @@ fn zirStructInitEmpty(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In...@@ -4493,6 +4495,18 @@ fn zirStructInitEmpty(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In
4493 });4495 });
4494}4496}
44954497
4498fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
4499 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
4500 const src = inst_data.src();
4501 return sema.mod.fail(&block.base, src, "TODO: Sema.zirStructInit", .{});
4502}
4503
4504fn zirFieldType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
4505 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
4506 const src = inst_data.src();
4507 return sema.mod.fail(&block.base, src, "TODO: Sema.zirFieldType", .{});
4508}
4509
4496fn requireFunctionBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void {4510fn requireFunctionBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void {
4497 if (sema.func == null) {4511 if (sema.func == null) {
4498 return sema.mod.fail(&block.base, src, "instruction illegal outside function body", .{});4512 return sema.mod.fail(&block.base, src, "instruction illegal outside function body", .{});
src/zir.zig+29
...@@ -674,6 +674,13 @@ pub const Inst = struct {...@@ -674,6 +674,13 @@ pub const Inst = struct {
674 /// A struct literal with a specified type, with no fields.674 /// A struct literal with a specified type, with no fields.
675 /// Uses the `un_node` field.675 /// Uses the `un_node` field.
676 struct_init_empty,676 struct_init_empty,
677 /// Given a struct, union, enum, or opaque and a field name, returns the field type.
678 /// Uses the `pl_node` field. Payload is `FieldType`.
679 field_type,
680 /// Finalizes a typed struct initialization, performs validation, and returns the
681 /// struct value.
682 /// Uses the `pl_node` field. Payload is `StructInit`.
683 struct_init,
677 /// Converts an integer into an enum value.684 /// Converts an integer into an enum value.
678 /// Uses `pl_node` with payload `Bin`. `lhs` is enum type, `rhs` is operand.685 /// Uses `pl_node` with payload `Bin`. `lhs` is enum type, `rhs` is operand.
679 int_to_enum,686 int_to_enum,
...@@ -839,6 +846,8 @@ pub const Inst = struct {...@@ -839,6 +846,8 @@ pub const Inst = struct {
839 .switch_block_ref_under_multi,846 .switch_block_ref_under_multi,
840 .validate_struct_init_ptr,847 .validate_struct_init_ptr,
841 .struct_init_empty,848 .struct_init_empty,
849 .struct_init,
850 .field_type,
842 .int_to_enum,851 .int_to_enum,
843 .enum_to_int,852 .enum_to_int,
844 => false,853 => false,
...@@ -1551,6 +1560,24 @@ pub const Inst = struct {...@@ -1551,6 +1560,24 @@ pub const Inst = struct {
1551 return @bitCast(f128, int_bits);1560 return @bitCast(f128, int_bits);
1552 }1561 }
1553 };1562 };
1563
1564 /// Trailing is an item per field.
1565 pub const StructInit = struct {
1566 fields_len: u32,
1567
1568 pub const Item = struct {
1569 /// The `field_type` ZIR instruction for this field init.
1570 field_type: Index,
1571 /// The field init expression to be used as the field value.
1572 init: Ref,
1573 };
1574 };
1575
1576 pub const FieldType = struct {
1577 container_type: Ref,
1578 /// Offset into `string_bytes`, null terminated.
1579 name_start: u32,
1580 };
1554};1581};
15551582
1556pub const SpecialProng = enum { none, @"else", under };1583pub const SpecialProng = enum { none, @"else", under };
...@@ -1665,6 +1692,8 @@ const Writer = struct {...@@ -1665,6 +1692,8 @@ const Writer = struct {
1665 .union_decl,1692 .union_decl,
1666 .enum_decl,1693 .enum_decl,
1667 .enum_decl_nonexhaustive,1694 .enum_decl_nonexhaustive,
1695 .struct_init,
1696 .field_type,
1668 => try self.writePlNode(stream, inst),1697 => try self.writePlNode(stream, inst),
16691698
1670 .add,1699 .add,