authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-21 19:11:36-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-21 19:11:36-07:00
log570ed7b3bf331c95d151a052b1c3117a502127f7
tree7416c6c6f0acbc25635d15b4a222eaf74b6f8050
parent4cfea2fbd51b5ecf7405c98432d14a8ace12247d

AstGen: implement `@bitCast` for other result location types


3 files changed, 29 insertions(+), 16 deletions(-)

src/AstGen.zig+24-11
...@@ -1125,7 +1125,7 @@ pub fn structInitExpr(...@@ -1125,7 +1125,7 @@ pub fn structInitExpr(
1125 }1125 }
1126 return init_inst;1126 return init_inst;
1127 },1127 },
1128 .ref => unreachable, // struct literal not valid as l-value1128 .ref => return astgen.failNode(node, "cannot take address of struct literal", .{}),
1129 .ty => |ty_inst| {1129 .ty => |ty_inst| {
1130 if (struct_init.ast.type_expr == 0) {1130 if (struct_init.ast.type_expr == 0) {
1131 return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst);1131 return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst);
...@@ -5819,7 +5819,7 @@ fn bitCast(...@@ -5819,7 +5819,7 @@ fn bitCast(
5819 const astgen = gz.astgen;5819 const astgen = gz.astgen;
5820 const dest_type = try typeExpr(gz, scope, lhs);5820 const dest_type = try typeExpr(gz, scope, lhs);
5821 switch (rl) {5821 switch (rl) {
5822 .none, .discard, .ty => {5822 .none, .none_or_ref, .discard, .ty => {
5823 const operand = try expr(gz, scope, .none, rhs);5823 const operand = try expr(gz, scope, .none, rhs);
5824 const result = try gz.addPlNode(.bitcast, node, Zir.Inst.Bin{5824 const result = try gz.addPlNode(.bitcast, node, Zir.Inst.Bin{
5825 .lhs = dest_type,5825 .lhs = dest_type,
...@@ -5827,21 +5827,34 @@ fn bitCast(...@@ -5827,21 +5827,34 @@ fn bitCast(
5827 });5827 });
5828 return rvalue(gz, scope, rl, result, node);5828 return rvalue(gz, scope, rl, result, node);
5829 },5829 },
5830 .ref, .none_or_ref => unreachable, // `@bitCast` is not allowed as an r-value.5830 .ref => {
5831 .ptr => |result_ptr| {5831 return astgen.failNode(node, "cannot take address of `@bitCast` result", .{});
5832 const casted_result_ptr = try gz.addUnNode(.bitcast_result_ptr, result_ptr, node);
5833 return expr(gz, scope, .{ .ptr = casted_result_ptr }, rhs);
5834 },5832 },
5835 .block_ptr => |block_ptr| {5833 .ptr, .inferred_ptr => |result_ptr| {
5836 return astgen.failNode(node, "TODO implement @bitCast with result location inferred peer types", .{});5834 return bitCastRlPtr(gz, scope, rl, node, dest_type, result_ptr, rhs);
5837 },5835 },
5838 .inferred_ptr => |result_alloc| {5836 .block_ptr => |block| {
5839 // TODO here we should be able to resolve the inference; we now have a type for the result.5837 return bitCastRlPtr(gz, scope, rl, node, dest_type, block.rl_ptr, rhs);
5840 return astgen.failNode(node, "TODO implement @bitCast with inferred-type result location pointer", .{});
5841 },5838 },
5842 }5839 }
5843}5840}
58445841
5842fn bitCastRlPtr(
5843 gz: *GenZir,
5844 scope: *Scope,
5845 rl: ResultLoc,
5846 node: ast.Node.Index,
5847 dest_type: Zir.Inst.Ref,
5848 result_ptr: Zir.Inst.Ref,
5849 rhs: ast.Node.Index,
5850) InnerError!Zir.Inst.Ref {
5851 const casted_result_ptr = try gz.addPlNode(.bitcast_result_ptr, node, Zir.Inst.Bin{
5852 .lhs = dest_type,
5853 .rhs = result_ptr,
5854 });
5855 return expr(gz, scope, .{ .ptr = casted_result_ptr }, rhs);
5856}
5857
5845fn typeOf(5858fn typeOf(
5846 gz: *GenZir,5859 gz: *GenZir,
5847 scope: *Scope,5860 scope: *Scope,
src/Sema.zig+3-3
...@@ -641,9 +641,9 @@ fn resolveInstConst(...@@ -641,9 +641,9 @@ fn resolveInstConst(
641}641}
642642
643fn zirBitcastResultPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {643fn zirBitcastResultPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
644 const tracy = trace(@src());644 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
645 defer tracy.end();645 const src = inst_data.src();
646 return sema.mod.fail(&block.base, sema.src, "TODO implement zir_sema.zirBitcastResultPtr", .{});646 return sema.mod.fail(&block.base, src, "TODO implement zir_sema.zirBitcastResultPtr", .{});
647}647}
648648
649fn zirCoerceResultPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {649fn zirCoerceResultPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
src/Zir.zig+2-2
...@@ -196,7 +196,7 @@ pub const Inst = struct {...@@ -196,7 +196,7 @@ pub const Inst = struct {
196 bitcast,196 bitcast,
197 /// A typed result location pointer is bitcasted to a new result location pointer.197 /// A typed result location pointer is bitcasted to a new result location pointer.
198 /// The new result location pointer has an inferred type.198 /// The new result location pointer has an inferred type.
199 /// Uses the un_node field.199 /// Uses the pl_node field with payload `Bin`.
200 bitcast_result_ptr,200 bitcast_result_ptr,
201 /// Bitwise NOT. `~`201 /// Bitwise NOT. `~`
202 /// Uses `un_node`.202 /// Uses `un_node`.
...@@ -2329,7 +2329,6 @@ const Writer = struct {...@@ -2329,7 +2329,6 @@ const Writer = struct {
2329 .byte_swap,2329 .byte_swap,
2330 .bit_reverse,2330 .bit_reverse,
2331 .elem_type,2331 .elem_type,
2332 .bitcast_result_ptr,
2333 => try self.writeUnNode(stream, inst),2332 => try self.writeUnNode(stream, inst),
23342333
2335 .ref,2334 .ref,
...@@ -2450,6 +2449,7 @@ const Writer = struct {...@@ -2450,6 +2449,7 @@ const Writer = struct {
2450 .reduce,2449 .reduce,
2451 .atomic_load,2450 .atomic_load,
2452 .bitcast,2451 .bitcast,
2452 .bitcast_result_ptr,
2453 => try self.writePlNodeBin(stream, inst),2453 => try self.writePlNodeBin(stream, inst),
24542454
2455 .call,2455 .call,