authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-23 23:40:10-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-23 23:40:10-07:00
log27fa4bc2bead4635038c06f8c1231cbc81674c2f
tree8456e2725136e0bb3baeb6160ca5958a6aac0b29
parentd2b06c2612fd3bf6d798373228d546c41ad76622

AstGen: support struct init with ref result location


3 files changed, 69 insertions(+), 31 deletions(-)

src/AstGen.zig+52-26
......@@ -1300,40 +1300,28 @@ pub fn structInitExpr(
13001300 }
13011301 return Zir.Inst.Ref.void_value;
13021302 },
1303 .none, .none_or_ref => {
1303 .ref => {
13041304 if (struct_init.ast.type_expr != 0) {
13051305 const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
1306 return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst);
1307 }
1308 const fields_list = try gpa.alloc(Zir.Inst.StructInitAnon.Item, struct_init.ast.fields.len);
1309 defer gpa.free(fields_list);
1310
1311 for (struct_init.ast.fields) |field_init, i| {
1312 const name_token = tree.firstToken(field_init) - 2;
1313 const str_index = try gz.identAsString(name_token);
1314
1315 fields_list[i] = .{
1316 .field_name = str_index,
1317 .init = try expr(gz, scope, .none, field_init),
1318 };
1306 return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst, .struct_init_ref);
1307 } else {
1308 return structInitExprRlNone(gz, scope, rl, node, struct_init, .struct_init_anon_ref);
13191309 }
1320 const init_inst = try gz.addPlNode(.struct_init_anon, node, Zir.Inst.StructInitAnon{
1321 .fields_len = @intCast(u32, fields_list.len),
1322 });
1323 try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +
1324 fields_list.len * @typeInfo(Zir.Inst.StructInitAnon.Item).Struct.fields.len);
1325 for (fields_list) |field| {
1326 _ = gz.astgen.addExtraAssumeCapacity(field);
1310 },
1311 .none, .none_or_ref => {
1312 if (struct_init.ast.type_expr != 0) {
1313 const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
1314 return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst, .struct_init);
1315 } else {
1316 return structInitExprRlNone(gz, scope, rl, node, struct_init, .struct_init_anon);
13271317 }
1328 return init_inst;
13291318 },
1330 .ref => return astgen.failNode(node, "cannot take address of struct literal", .{}),
13311319 .ty => |ty_inst| {
13321320 if (struct_init.ast.type_expr == 0) {
1333 return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst);
1321 return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst, .struct_init);
13341322 }
13351323 const inner_ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
1336 const result = try structInitExprRlTy(gz, scope, rl, node, struct_init, inner_ty_inst);
1324 const result = try structInitExprRlTy(gz, scope, rl, node, struct_init, inner_ty_inst, .struct_init);
13371325 return rvalue(gz, scope, rl, result, node);
13381326 },
13391327 .ptr, .inferred_ptr => |ptr_inst| return structInitExprRlPtr(gz, scope, rl, node, struct_init, ptr_inst),
......@@ -1341,6 +1329,41 @@ pub fn structInitExpr(
13411329 }
13421330}
13431331
1332pub fn structInitExprRlNone(
1333 gz: *GenZir,
1334 scope: *Scope,
1335 rl: ResultLoc,
1336 node: ast.Node.Index,
1337 struct_init: ast.full.StructInit,
1338 tag: Zir.Inst.Tag,
1339) InnerError!Zir.Inst.Ref {
1340 const astgen = gz.astgen;
1341 const gpa = astgen.gpa;
1342 const tree = &astgen.file.tree;
1343
1344 const fields_list = try gpa.alloc(Zir.Inst.StructInitAnon.Item, struct_init.ast.fields.len);
1345 defer gpa.free(fields_list);
1346
1347 for (struct_init.ast.fields) |field_init, i| {
1348 const name_token = tree.firstToken(field_init) - 2;
1349 const str_index = try gz.identAsString(name_token);
1350
1351 fields_list[i] = .{
1352 .field_name = str_index,
1353 .init = try expr(gz, scope, .none, field_init),
1354 };
1355 }
1356 const init_inst = try gz.addPlNode(tag, node, Zir.Inst.StructInitAnon{
1357 .fields_len = @intCast(u32, fields_list.len),
1358 });
1359 try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +
1360 fields_list.len * @typeInfo(Zir.Inst.StructInitAnon.Item).Struct.fields.len);
1361 for (fields_list) |field| {
1362 _ = gz.astgen.addExtraAssumeCapacity(field);
1363 }
1364 return init_inst;
1365}
1366
13441367pub fn structInitExprRlPtr(
13451368 gz: *GenZir,
13461369 scope: *Scope,
......@@ -1380,6 +1403,7 @@ pub fn structInitExprRlTy(
13801403 node: ast.Node.Index,
13811404 struct_init: ast.full.StructInit,
13821405 ty_inst: Zir.Inst.Ref,
1406 tag: Zir.Inst.Tag,
13831407) InnerError!Zir.Inst.Ref {
13841408 const astgen = gz.astgen;
13851409 const gpa = astgen.gpa;
......@@ -1401,7 +1425,7 @@ pub fn structInitExprRlTy(
14011425 .init = try expr(gz, scope, .{ .ty = field_ty_inst }, field_init),
14021426 };
14031427 }
1404 const init_inst = try gz.addPlNode(.struct_init, node, Zir.Inst.StructInit{
1428 const init_inst = try gz.addPlNode(tag, node, Zir.Inst.StructInit{
14051429 .fields_len = @intCast(u32, fields_list.len),
14061430 });
14071431 try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +
......@@ -1886,7 +1910,9 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner
18861910 .switch_capture_else_ref,
18871911 .struct_init_empty,
18881912 .struct_init,
1913 .struct_init_ref,
18891914 .struct_init_anon,
1915 .struct_init_anon_ref,
18901916 .array_init,
18911917 .array_init_anon,
18921918 .array_init_ref,
src/Sema.zig+7-5
......@@ -256,11 +256,13 @@ pub fn analyzeBody(
256256 .typeof_log2_int_type => try sema.zirTypeofLog2IntType(block, inst),
257257 .xor => try sema.zirBitwise(block, inst, .xor),
258258 .struct_init_empty => try sema.zirStructInitEmpty(block, inst),
259 .struct_init => try sema.zirStructInit(block, inst),
260 .struct_init_anon => try sema.zirStructInitAnon(block, inst),
259 .struct_init => try sema.zirStructInit(block, inst, false),
260 .struct_init_ref => try sema.zirStructInit(block, inst, true),
261 .struct_init_anon => try sema.zirStructInitAnon(block, inst, false),
262 .struct_init_anon_ref => try sema.zirStructInitAnon(block, inst, true),
261263 .array_init => try sema.zirArrayInit(block, inst, false),
262 .array_init_anon => try sema.zirArrayInitAnon(block, inst, false),
263264 .array_init_ref => try sema.zirArrayInit(block, inst, true),
265 .array_init_anon => try sema.zirArrayInitAnon(block, inst, false),
264266 .array_init_anon_ref => try sema.zirArrayInitAnon(block, inst, true),
265267 .union_init_ptr => try sema.zirUnionInitPtr(block, inst),
266268 .field_type => try sema.zirFieldType(block, inst),
......@@ -5078,13 +5080,13 @@ fn zirUnionInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner
50785080 return sema.mod.fail(&block.base, src, "TODO: Sema.zirUnionInitPtr", .{});
50795081}
50805082
5081fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
5083fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: bool) InnerError!*Inst {
50825084 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
50835085 const src = inst_data.src();
50845086 return sema.mod.fail(&block.base, src, "TODO: Sema.zirStructInit", .{});
50855087}
50865088
5087fn zirStructInitAnon(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
5089fn zirStructInitAnon(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: bool) InnerError!*Inst {
50885090 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
50895091 const src = inst_data.src();
50905092 return sema.mod.fail(&block.base, src, "TODO: Sema.zirStructInitAnon", .{});
src/Zir.zig+10
......@@ -660,9 +660,15 @@ pub const Inst = struct {
660660 /// struct value.
661661 /// Uses the `pl_node` field. Payload is `StructInit`.
662662 struct_init,
663 /// Struct initialization syntax, make the result a pointer.
664 /// Uses the `pl_node` field. Payload is `StructInit`.
665 struct_init_ref,
663666 /// Struct initialization without a type.
664667 /// Uses the `pl_node` field. Payload is `StructInitAnon`.
665668 struct_init_anon,
669 /// Anonymous struct initialization syntax, make the result a pointer.
670 /// Uses the `pl_node` field. Payload is `StructInitAnon`.
671 struct_init_anon_ref,
666672 /// Array initialization syntax.
667673 /// Uses the `pl_node` field. Payload is `MultiOp`.
668674 array_init,
......@@ -1093,7 +1099,9 @@ pub const Inst = struct {
10931099 .validate_array_init_ptr,
10941100 .struct_init_empty,
10951101 .struct_init,
1102 .struct_init_ref,
10961103 .struct_init_anon,
1104 .struct_init_anon_ref,
10971105 .array_init,
10981106 .array_init_anon,
10991107 .array_init_ref,
......@@ -2442,7 +2450,9 @@ const Writer = struct {
24422450 .slice_end,
24432451 .slice_sentinel,
24442452 .struct_init,
2453 .struct_init_ref,
24452454 .struct_init_anon,
2455 .struct_init_anon_ref,
24462456 .array_init,
24472457 .array_init_anon,
24482458 .array_init_ref,