Commit e315120b79
Changed files (5)
lib
std
zig
lib/std/zig/render.zig
@@ -1590,7 +1590,6 @@ fn renderStructInit(
return renderToken(ais, tree, rbrace, space);
}
-// TODO: handle comments between elements
fn renderArrayInit(
gpa: *Allocator,
ais: *Ais,
src/AstGen.zig
@@ -822,15 +822,20 @@ pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inn
.@"errdefer" => return astgen.failNode(node, "TODO implement astgen.expr for .errdefer", .{}),
.@"try" => return astgen.failNode(node, "TODO implement astgen.expr for .Try", .{}),
- .array_init_one,
- .array_init_one_comma,
- .array_init_dot_two,
- .array_init_dot_two_comma,
+ .array_init_one, .array_init_one_comma => {
+ var elements: [1]ast.Node.Index = undefined;
+ return arrayInitExpr(gz, scope, rl, node, tree.arrayInitOne(&elements, node));
+ },
+ .array_init_dot_two, .array_init_dot_two_comma => {
+ var elements: [2]ast.Node.Index = undefined;
+ return arrayInitExpr(gz, scope, rl, node, tree.arrayInitDotTwo(&elements, node));
+ },
.array_init_dot,
.array_init_dot_comma,
+ => return arrayInitExpr(gz, scope, rl, node, tree.arrayInitDot(node)),
.array_init,
.array_init_comma,
- => return astgen.failNode(node, "TODO implement astgen.expr for array literals", .{}),
+ => return arrayInitExpr(gz, scope, rl, node, tree.arrayInit(node)),
.struct_init_one, .struct_init_one_comma => {
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
}
}
+pub fn arrayInitExpr(
+ gz: *GenZir,
+ scope: *Scope,
+ rl: ResultLoc,
+ node: ast.Node.Index,
+ array_init: ast.full.ArrayInit,
+) InnerError!Zir.Inst.Ref {
+ const astgen = gz.astgen;
+ const tree = &astgen.file.tree;
+ const gpa = astgen.gpa;
+ const node_tags = tree.nodes.items(.tag);
+ const main_tokens = tree.nodes.items(.main_token);
+
+ assert(array_init.ast.elements.len != 0); // Otherwise it would be struct init.
+
+ const types: struct {
+ array: Zir.Inst.Ref,
+ elem: Zir.Inst.Ref,
+ } = inst: {
+ if (array_init.ast.type_expr == 0) break :inst .{
+ .array = .none,
+ .elem = .none,
+ };
+
+ infer: {
+ const array_type: ast.full.ArrayType = switch (node_tags[array_init.ast.type_expr]) {
+ .array_type => tree.arrayType(array_init.ast.type_expr),
+ .array_type_sentinel => tree.arrayTypeSentinel(array_init.ast.type_expr),
+ else => break :infer,
+ };
+ // This intentionally does not support `@"_"` syntax.
+ if (node_tags[array_type.ast.elem_count] == .identifier and
+ mem.eql(u8, tree.tokenSlice(main_tokens[array_type.ast.elem_count]), "_"))
+ {
+ const tag: Zir.Inst.Tag = switch (node_tags[array_init.ast.type_expr]) {
+ .array_type => .array_type,
+ .array_type_sentinel => .array_type_sentinel,
+ else => unreachable,
+ };
+ const len_inst = try gz.addInt(array_init.ast.elements.len);
+ const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type);
+ const array_type_inst = try gz.addBin(tag, len_inst, elem_type);
+ break :inst .{
+ .array = array_type_inst,
+ .elem = elem_type,
+ };
+ }
+ }
+ const array_type_inst = try typeExpr(gz, scope, array_init.ast.type_expr);
+ const elem_type = try gz.addUnNode(.elem_type, array_type_inst, array_init.ast.type_expr);
+ break :inst .{
+ .array = array_type_inst,
+ .elem = elem_type,
+ };
+ };
+
+ switch (rl) {
+ .discard => {
+ for (array_init.ast.elements) |elem_init| {
+ _ = try expr(gz, scope, .discard, elem_init);
+ }
+ return Zir.Inst.Ref.void_value;
+ },
+ .ref => {
+ if (types.array != .none) {
+ return arrayInitExprRlTy(gz, scope, rl, node, array_init.ast.elements, types.array, types.elem, .array_init_ref);
+ } else {
+ return arrayInitExprRlNone(gz, scope, rl, node, array_init.ast.elements, .array_init_anon_ref);
+ }
+ },
+ .none, .none_or_ref => {
+ if (types.array != .none) {
+ return arrayInitExprRlTy(gz, scope, rl, node, array_init.ast.elements, types.array, types.elem, .array_init);
+ } else {
+ return arrayInitExprRlNone(gz, scope, rl, node, array_init.ast.elements, .array_init_anon);
+ }
+ },
+ .ty => |ty_inst| {
+ if (types.array != .none) {
+ const result = try arrayInitExprRlTy(gz, scope, rl, node, array_init.ast.elements, types.array, types.elem, .array_init);
+ return rvalue(gz, scope, rl, result, node);
+ } else {
+ const elem_type = try gz.addUnNode(.elem_type, ty_inst, node);
+ return arrayInitExprRlTy(gz, scope, rl, node, array_init.ast.elements, ty_inst, elem_type, .array_init);
+ }
+ },
+ .ptr, .inferred_ptr => |ptr_inst| {
+ return arrayInitExprRlPtr(gz, scope, rl, node, array_init.ast.elements, ptr_inst);
+ },
+ .block_ptr => |block_gz| {
+ return arrayInitExprRlPtr(gz, scope, rl, node, array_init.ast.elements, block_gz.rl_ptr);
+ },
+ }
+}
+
+pub fn arrayInitExprRlNone(
+ gz: *GenZir,
+ scope: *Scope,
+ rl: ResultLoc,
+ node: ast.Node.Index,
+ elements: []const ast.Node.Index,
+ tag: Zir.Inst.Tag,
+) InnerError!Zir.Inst.Ref {
+ const astgen = gz.astgen;
+ const gpa = astgen.gpa;
+ const elem_list = try gpa.alloc(Zir.Inst.Ref, elements.len);
+ defer gpa.free(elem_list);
+
+ for (elements) |elem_init, i| {
+ elem_list[i] = try expr(gz, scope, .none, elem_init);
+ }
+ const init_inst = try gz.addPlNode(tag, node, Zir.Inst.MultiOp{
+ .operands_len = @intCast(u32, elem_list.len),
+ });
+ try astgen.appendRefs(elem_list);
+ return init_inst;
+}
+
+pub fn arrayInitExprRlTy(
+ gz: *GenZir,
+ scope: *Scope,
+ rl: ResultLoc,
+ node: ast.Node.Index,
+ elements: []const ast.Node.Index,
+ array_ty_inst: Zir.Inst.Ref,
+ elem_ty_inst: Zir.Inst.Ref,
+ tag: Zir.Inst.Tag,
+) InnerError!Zir.Inst.Ref {
+ const astgen = gz.astgen;
+ const gpa = astgen.gpa;
+
+ const elem_list = try gpa.alloc(Zir.Inst.Ref, elements.len);
+ defer gpa.free(elem_list);
+
+ const elem_rl: ResultLoc = .{ .ty = elem_ty_inst };
+
+ for (elements) |elem_init, i| {
+ elem_list[i] = try expr(gz, scope, elem_rl, elem_init);
+ }
+ const init_inst = try gz.addPlNode(tag, node, Zir.Inst.MultiOp{
+ .operands_len = @intCast(u32, elem_list.len),
+ });
+ try astgen.appendRefs(elem_list);
+ return init_inst;
+}
+
+pub fn arrayInitExprRlPtr(
+ gz: *GenZir,
+ scope: *Scope,
+ rl: ResultLoc,
+ node: ast.Node.Index,
+ elements: []const ast.Node.Index,
+ result_ptr: Zir.Inst.Ref,
+) InnerError!Zir.Inst.Ref {
+ const astgen = gz.astgen;
+ const gpa = astgen.gpa;
+
+ const elem_ptr_list = try gpa.alloc(Zir.Inst.Index, elements.len);
+ defer gpa.free(elem_ptr_list);
+
+ for (elements) |elem_init, i| {
+ const index_inst = try gz.addInt(i);
+ const elem_ptr = try gz.addPlNode(.elem_ptr_node, elem_init, Zir.Inst.Bin{
+ .lhs = result_ptr,
+ .rhs = index_inst,
+ });
+ elem_ptr_list[i] = gz.refToIndex(elem_ptr).?;
+ _ = try expr(gz, scope, .{ .ptr = elem_ptr }, elem_init);
+ }
+ _ = try gz.addPlNode(.validate_array_init_ptr, node, Zir.Inst.Block{
+ .body_len = @intCast(u32, elem_ptr_list.len),
+ });
+ try astgen.extra.appendSlice(gpa, elem_ptr_list);
+ return .void_value;
+}
+
pub fn structInitExpr(
gz: *GenZir,
scope: *Scope,
@@ -911,7 +1092,14 @@ pub fn structInitExpr(
return init_inst;
},
.ref => unreachable, // struct literal not valid as l-value
- .ty => |ty_inst| return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst),
+ .ty => |ty_inst| {
+ if (struct_init.ast.type_expr == 0) {
+ return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst);
+ }
+ const inner_ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
+ const result = try structInitExprRlTy(gz, scope, rl, node, struct_init, inner_ty_inst);
+ return rvalue(gz, scope, rl, result, node);
+ },
.ptr, .inferred_ptr => |ptr_inst| return structInitExprRlPtr(gz, scope, rl, node, struct_init, ptr_inst),
.block_ptr => |block_gz| return structInitExprRlPtr(gz, scope, rl, node, struct_init, block_gz.rl_ptr),
}
@@ -942,11 +1130,11 @@ pub fn structInitExprRlPtr(
field_ptr_list[i] = gz.refToIndex(field_ptr).?;
_ = try expr(gz, scope, .{ .ptr = field_ptr }, field_init);
}
- const validate_inst = try gz.addPlNode(.validate_struct_init_ptr, node, Zir.Inst.Block{
+ _ = try gz.addPlNode(.validate_struct_init_ptr, node, Zir.Inst.Block{
.body_len = @intCast(u32, field_ptr_list.len),
});
try astgen.extra.appendSlice(gpa, field_ptr_list);
- return validate_inst;
+ return .void_value;
}
pub fn structInitExprRlTy(
@@ -1336,6 +1524,7 @@ fn blockExprStmts(
.array_mul,
.array_type,
.array_type_sentinel,
+ .elem_type,
.indexable_ptr_len,
.as,
.as_node,
@@ -1393,8 +1582,6 @@ fn blockExprStmts(
.param_type,
.ptrtoint,
.ref,
- .ret_ptr,
- .ret_type,
.shl,
.shr,
.str,
@@ -1453,6 +1640,10 @@ fn blockExprStmts(
.struct_init_empty,
.struct_init,
.struct_init_anon,
+ .array_init,
+ .array_init_anon,
+ .array_init_ref,
+ .array_init_anon_ref,
.union_init_ptr,
.field_type,
.field_type_ref,
@@ -1469,18 +1660,12 @@ fn blockExprStmts(
.type_info,
.size_of,
.bit_size_of,
- .this,
- .ret_addr,
- .builtin_src,
.add_with_overflow,
.sub_with_overflow,
.mul_with_overflow,
.shl_with_overflow,
.log2_int_type,
.typeof_log2_int_type,
- .error_return_trace,
- .frame,
- .frame_address,
.ptr_to_int,
.align_of,
.bool_to_int,
@@ -1575,6 +1760,7 @@ fn blockExprStmts(
.repeat,
.repeat_inline,
.validate_struct_init_ptr,
+ .validate_array_init_ptr,
.panic,
.set_align_stack,
.set_cold,
@@ -2572,13 +2758,17 @@ fn structDeclInner(
field_index += 1;
}
- if (field_index != 0) {
+ {
const empty_slot_count = 16 - (field_index % 16);
- cur_bit_bag >>= @intCast(u5, empty_slot_count * 2);
+ if (empty_slot_count < 16) {
+ cur_bit_bag >>= @intCast(u5, empty_slot_count * 2);
+ }
}
- if (wip_decls.decl_index != 0) {
+ {
const empty_slot_count = 16 - (wip_decls.decl_index % 16);
- wip_decls.cur_bit_bag >>= @intCast(u5, empty_slot_count * 2);
+ if (empty_slot_count < 16) {
+ wip_decls.cur_bit_bag >>= @intCast(u5, empty_slot_count * 2);
+ }
}
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
const operand_node = node_datas[node].lhs;
const operand: Zir.Inst.Ref = if (operand_node != 0) operand: {
const rl: ResultLoc = if (nodeMayNeedMemoryLocation(tree, operand_node)) .{
- .ptr = try gz.addNode(.ret_ptr, node),
+ .ptr = try gz.addNodeExtended(.ret_ptr, node),
} else .{
- .ty = try gz.addNode(.ret_type, node),
+ .ty = try gz.addNodeExtended(.ret_type, node),
};
break :operand try expr(gz, scope, rl, operand_node);
} else .void_value;
@@ -5203,12 +5393,12 @@ fn builtinCall(
.breakpoint => return simpleNoOpVoid(gz, scope, rl, node, .breakpoint),
.fence => return simpleNoOpVoid(gz, scope, rl, node, .fence),
- .This => return rvalue(gz, scope, rl, try gz.addNode(.this, node), node),
- .return_address => return rvalue(gz, scope, rl, try gz.addNode(.ret_addr, node), node),
- .src => return rvalue(gz, scope, rl, try gz.addNode(.builtin_src, node), node),
- .error_return_trace => return rvalue(gz, scope, rl, try gz.addNode(.error_return_trace, node), node),
- .frame => return rvalue(gz, scope, rl, try gz.addNode(.frame, node), node),
- .frame_address => return rvalue(gz, scope, rl, try gz.addNode(.frame_address, node), node),
+ .This => return rvalue(gz, scope, rl, try gz.addNodeExtended(.this, node), node),
+ .return_address => return rvalue(gz, scope, rl, try gz.addNodeExtended(.ret_addr, node), node),
+ .src => return rvalue(gz, scope, rl, try gz.addNodeExtended(.builtin_src, node), node),
+ .error_return_trace => return rvalue(gz, scope, rl, try gz.addNodeExtended(.error_return_trace, node), node),
+ .frame => return rvalue(gz, scope, rl, try gz.addNodeExtended(.frame, node), node),
+ .frame_address => return rvalue(gz, scope, rl, try gz.addNodeExtended(.frame_address, node), node),
.type_info => return simpleUnOpType(gz, scope, rl, node, params[0], .type_info),
.size_of => return simpleUnOpType(gz, scope, rl, node, params[0], .size_of),
src/Module.zig
@@ -1622,6 +1622,22 @@ pub const Scope = struct {
});
}
+ pub fn addNodeExtended(
+ gz: *GenZir,
+ opcode: Zir.Inst.Extended,
+ /// Absolute node index. This function does the conversion to offset from Decl.
+ src_node: ast.Node.Index,
+ ) !Zir.Inst.Ref {
+ return gz.add(.{
+ .tag = .extended,
+ .data = .{ .extended = .{
+ .opcode = opcode,
+ .small = undefined,
+ .operand = @bitCast(u32, gz.nodeIndexToRelative(src_node)),
+ } },
+ });
+ }
+
/// Asserts that `str` is 8 or fewer bytes.
pub fn addSmallStr(
gz: *GenZir,
@@ -2583,6 +2599,7 @@ pub fn astGenFile(mod: *Module, file: *Scope.File, prog_node: *std.Progress.Node
return error.AnalysisFail;
}
+ log.debug("AstGen success: {s}", .{file.sub_file_path});
file.status = .success;
}
src/Sema.zig
@@ -175,6 +175,7 @@ pub fn analyzeBody(
.elem_ptr_node => try sema.zirElemPtrNode(block, inst),
.elem_val => try sema.zirElemVal(block, inst),
.elem_val_node => try sema.zirElemValNode(block, inst),
+ .elem_type => try sema.zirElemType(block, inst),
.enum_literal => try sema.zirEnumLiteral(block, inst),
.enum_literal_small => try sema.zirEnumLiteralSmall(block, inst),
.enum_to_int => try sema.zirEnumToInt(block, inst),
@@ -223,8 +224,6 @@ pub fn analyzeBody(
.ptr_type_simple => try sema.zirPtrTypeSimple(block, inst),
.ptrtoint => try sema.zirPtrtoint(block, inst),
.ref => try sema.zirRef(block, inst),
- .ret_ptr => try sema.zirRetPtr(block, inst),
- .ret_type => try sema.zirRetType(block, inst),
.shl => try sema.zirShl(block, inst),
.shr => try sema.zirShr(block, inst),
.slice_end => try sema.zirSliceEnd(block, inst),
@@ -252,9 +251,6 @@ pub fn analyzeBody(
.type_info => try sema.zirTypeInfo(block, inst),
.size_of => try sema.zirSizeOf(block, inst),
.bit_size_of => try sema.zirBitSizeOf(block, inst),
- .this => try sema.zirThis(block, inst),
- .ret_addr => try sema.zirRetAddr(block, inst),
- .builtin_src => try sema.zirBuiltinSrc(block, inst),
.typeof => try sema.zirTypeof(block, inst),
.typeof_elem => try sema.zirTypeofElem(block, inst),
.typeof_peer => try sema.zirTypeofPeer(block, inst),
@@ -264,12 +260,13 @@ pub fn analyzeBody(
.struct_init_empty => try sema.zirStructInitEmpty(block, inst),
.struct_init => try sema.zirStructInit(block, inst),
.struct_init_anon => try sema.zirStructInitAnon(block, inst),
+ .array_init => try sema.zirArrayInit(block, inst, false),
+ .array_init_anon => try sema.zirArrayInitAnon(block, inst, false),
+ .array_init_ref => try sema.zirArrayInit(block, inst, true),
+ .array_init_anon_ref => try sema.zirArrayInitAnon(block, inst, true),
.union_init_ptr => try sema.zirUnionInitPtr(block, inst),
.field_type => try sema.zirFieldType(block, inst),
.field_type_ref => try sema.zirFieldTypeRef(block, inst),
- .error_return_trace => try sema.zirErrorReturnTrace(block, inst),
- .frame => try sema.zirFrame(block, inst),
- .frame_address => try sema.zirFrameAddress(block, inst),
.ptr_to_int => try sema.zirPtrToInt(block, inst),
.align_of => try sema.zirAlignOf(block, inst),
.bool_to_int => try sema.zirBoolToInt(block, inst),
@@ -435,6 +432,10 @@ pub fn analyzeBody(
try sema.zirValidateStructInitPtr(block, inst);
continue;
},
+ .validate_array_init_ptr => {
+ try sema.zirValidateArrayInitPtr(block, inst);
+ continue;
+ },
.@"export" => {
try sema.zirExport(block, inst);
continue;
@@ -499,6 +500,28 @@ pub fn analyzeBody(
}
}
+fn zirExtended(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
+ const extended = sema.code.instructions.items(.data)[inst].extended;
+ switch (extended.opcode) {
+ // zig fmt: off
+ .func => return sema.zirFuncExtended( block, extended),
+ .ret_ptr => return sema.zirRetPtr( block, extended),
+ .ret_type => return sema.zirRetType( block, extended),
+ .this => return sema.zirThis( block, extended),
+ .ret_addr => return sema.zirRetAddr( block, extended),
+ .builtin_src => return sema.zirBuiltinSrc( block, extended),
+ .error_return_trace => return sema.zirErrorReturnTrace(block, extended),
+ .frame => return sema.zirFrame( block, extended),
+ .frame_address => return sema.zirFrameAddress( block, extended),
+ .c_undef => return sema.zirCUndef( block, extended),
+ .c_include => return sema.zirCInclude( block, extended),
+ .c_define => return sema.zirCDefine( block, extended),
+ .wasm_memory_size => return sema.zirWasmMemorySize( block, extended),
+ .wasm_memory_grow => return sema.zirWasmMemoryGrow( block, extended),
+ // zig fmt: on
+ }
+}
+
/// TODO when we rework TZIR memory layout, this function will no longer have a possible error.
pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) error{OutOfMemory}!*ir.Inst {
var i: usize = @enumToInt(zir_ref);
@@ -990,11 +1013,15 @@ fn zirErrorSetDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner
return sema.mod.fail(&block.base, sema.src, "TODO implement zirErrorSetDecl", .{});
}
-fn zirRetPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
+fn zirRetPtr(
+ sema: *Sema,
+ block: *Scope.Block,
+ extended: Zir.Inst.Extended.InstData,
+) InnerError!*Inst {
const tracy = trace(@src());
defer tracy.end();
- const src: LazySrcLoc = .unneeded;
+ const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
try sema.requireFunctionBlock(block, src);
const fn_ty = sema.func.?.owner_decl.typed_value.most_recent.typed_value.ty;
const ret_type = fn_ty.fnReturnType();
@@ -1011,11 +1038,15 @@ fn zirRef(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*In
return sema.analyzeRef(block, inst_data.src(), operand);
}
-fn zirRetType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
+fn zirRetType(
+ sema: *Sema,
+ block: *Scope.Block,
+ extended: Zir.Inst.Extended.InstData,
+) InnerError!*Inst {
const tracy = trace(@src());
defer tracy.end();
- const src: LazySrcLoc = .unneeded;
+ const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
try sema.requireFunctionBlock(block, src);
const fn_ty = sema.func.?.owner_decl.typed_value.most_recent.typed_value.ty;
const ret_type = fn_ty.fnReturnType();
@@ -1247,6 +1278,12 @@ fn zirValidateStructInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Ind
}
}
+fn zirValidateArrayInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!void {
+ const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
+ const src = inst_data.src();
+ return sema.mod.fail(&block.base, src, "TODO implement Sema.zirValidateArrayInitPtr", .{});
+}
+
fn failWithBadFieldAccess(
sema: *Sema,
block: *Scope.Block,
@@ -2064,6 +2101,14 @@ fn zirOptionalTypeFromPtrElem(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.I
return sema.mod.constType(sema.arena, inst_data.src(), opt_ty);
}
+fn zirElemType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
+ const inst_data = sema.code.instructions.items(.data)[inst].un_node;
+ const src = inst_data.src();
+ const array_type = try sema.resolveType(block, src, inst_data.operand);
+ const elem_type = array_type.elemType();
+ return sema.mod.constType(sema.arena, src, elem_type);
+}
+
fn zirArrayType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
const tracy = trace(@src());
defer tracy.end();
@@ -4512,21 +4557,30 @@ fn zirBitSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr
return sema.mod.constIntUnsigned(sema.arena, src, Type.initTag(.comptime_int), bit_size);
}
-fn zirThis(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
- const src_node = sema.code.instructions.items(.data)[inst].node;
- const src: LazySrcLoc = .{ .node_offset = src_node };
+fn zirThis(
+ sema: *Sema,
+ block: *Scope.Block,
+ extended: Zir.Inst.Extended.InstData,
+) InnerError!*Inst {
+ const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirThis", .{});
}
-fn zirRetAddr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
- const src_node = sema.code.instructions.items(.data)[inst].node;
- const src: LazySrcLoc = .{ .node_offset = src_node };
+fn zirRetAddr(
+ sema: *Sema,
+ block: *Scope.Block,
+ extended: Zir.Inst.Extended.InstData,
+) InnerError!*Inst {
+ const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirRetAddr", .{});
}
-fn zirBuiltinSrc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
- const src_node = sema.code.instructions.items(.data)[inst].node;
- const src: LazySrcLoc = .{ .node_offset = src_node };
+fn zirBuiltinSrc(
+ sema: *Sema,
+ block: *Scope.Block,
+ extended: Zir.Inst.Extended.InstData,
+) InnerError!*Inst {
+ const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirBuiltinSrc", .{});
}
@@ -4983,6 +5037,18 @@ fn zirStructInitAnon(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inn
return sema.mod.fail(&block.base, src, "TODO: Sema.zirStructInitAnon", .{});
}
+fn zirArrayInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: bool) InnerError!*Inst {
+ const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
+ const src = inst_data.src();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirArrayInit", .{});
+}
+
+fn zirArrayInitAnon(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: bool) InnerError!*Inst {
+ const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
+ const src = inst_data.src();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirArrayInitAnon", .{});
+}
+
fn zirFieldTypeRef(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
const src = inst_data.src();
@@ -4995,21 +5061,30 @@ fn zirFieldType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr
return sema.mod.fail(&block.base, src, "TODO: Sema.zirFieldType", .{});
}
-fn zirErrorReturnTrace(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
- const inst_data = sema.code.instructions.items(.data)[inst].un_node;
- const src = inst_data.src();
+fn zirErrorReturnTrace(
+ sema: *Sema,
+ block: *Scope.Block,
+ extended: Zir.Inst.Extended.InstData,
+) InnerError!*Inst {
+ const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
return sema.mod.fail(&block.base, src, "TODO: Sema.zirErrorReturnTrace", .{});
}
-fn zirFrame(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
- const inst_data = sema.code.instructions.items(.data)[inst].un_node;
- const src = inst_data.src();
+fn zirFrame(
+ sema: *Sema,
+ block: *Scope.Block,
+ extended: Zir.Inst.Extended.InstData,
+) InnerError!*Inst {
+ const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
return sema.mod.fail(&block.base, src, "TODO: Sema.zirFrame", .{});
}
-fn zirFrameAddress(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
- const inst_data = sema.code.instructions.items(.data)[inst].un_node;
- const src = inst_data.src();
+fn zirFrameAddress(
+ sema: *Sema,
+ block: *Scope.Block,
+ extended: Zir.Inst.Extended.InstData,
+) InnerError!*Inst {
+ const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
return sema.mod.fail(&block.base, src, "TODO: Sema.zirFrameAddress", .{});
}
@@ -5295,24 +5370,9 @@ fn zirBuiltinAsyncCall(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) I
return sema.mod.fail(&block.base, src, "TODO: Sema.zirBuiltinAsyncCall", .{});
}
-fn zirExtended(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
- const extended = sema.code.instructions.items(.data)[inst].extended;
- switch (extended.opcode) {
- // zig fmt: off
- .func => return sema.zirFuncExtended( block, inst, extended),
- .c_undef => return sema.zirCUndef( block, inst, extended),
- .c_include => return sema.zirCInclude( block, inst, extended),
- .c_define => return sema.zirCDefine( block, inst, extended),
- .wasm_memory_size => return sema.zirWasmMemorySize(block, inst, extended),
- .wasm_memory_grow => return sema.zirWasmMemoryGrow(block, inst, extended),
- // zig fmt: on
- }
-}
-
fn zirFuncExtended(
sema: *Sema,
block: *Scope.Block,
- inst: Zir.Inst.Index,
extended: Zir.Inst.Extended.InstData,
) InnerError!*Inst {
const tracy = trace(@src());
@@ -5364,7 +5424,6 @@ fn zirFuncExtended(
fn zirCUndef(
sema: *Sema,
block: *Scope.Block,
- inst: Zir.Inst.Index,
extended: Zir.Inst.Extended.InstData,
) InnerError!*Inst {
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
@@ -5375,7 +5434,6 @@ fn zirCUndef(
fn zirCInclude(
sema: *Sema,
block: *Scope.Block,
- inst: Zir.Inst.Index,
extended: Zir.Inst.Extended.InstData,
) InnerError!*Inst {
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
@@ -5386,7 +5444,6 @@ fn zirCInclude(
fn zirCDefine(
sema: *Sema,
block: *Scope.Block,
- inst: Zir.Inst.Index,
extended: Zir.Inst.Extended.InstData,
) InnerError!*Inst {
const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
@@ -5397,7 +5454,6 @@ fn zirCDefine(
fn zirWasmMemorySize(
sema: *Sema,
block: *Scope.Block,
- inst: Zir.Inst.Index,
extended: Zir.Inst.Extended.InstData,
) InnerError!*Inst {
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
@@ -5408,7 +5464,6 @@ fn zirWasmMemorySize(
fn zirWasmMemoryGrow(
sema: *Sema,
block: *Scope.Block,
- inst: Zir.Inst.Index,
extended: Zir.Inst.Extended.InstData,
) InnerError!*Inst {
const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
src/Zir.zig
@@ -169,6 +169,9 @@ pub const Inst = struct {
/// `[N:S]T` syntax. No source location provided.
/// Uses the `array_type_sentinel` field.
array_type_sentinel,
+ /// Given an array type, returns the element type.
+ /// Uses the `un_node` union field.
+ elem_type,
/// Given a pointer to an indexable object, returns the len property. This is
/// used by for loops. This instruction also emits a for-loop specific compile
/// error if the indexable object is not indexable.
@@ -457,12 +460,6 @@ pub const Inst = struct {
/// instruction.
/// Uses the `un_tok` union field.
ref,
- /// Obtains a pointer to the return value.
- /// Uses the `node` union field.
- ret_ptr,
- /// Obtains the return type of the in-scope function.
- /// Uses the `node` union field.
- ret_type,
/// Sends control flow back to the function's callee.
/// Includes an operand as the return value.
/// Includes an AST node source location.
@@ -674,6 +671,13 @@ pub const Inst = struct {
/// because it must use one of them to find out the struct type.
/// Uses the `pl_node` field. Payload is `Block`.
validate_struct_init_ptr,
+ /// Given a set of `elem_ptr_node` instructions, assumes they are all part of an
+ /// array initialization expression, and emits a compile error if the number of
+ /// elements does not match the array type.
+ /// This instruction asserts that there is at least one elem_ptr_node instruction,
+ /// because it must use one of them to find out the array type.
+ /// Uses the `pl_node` field. Payload is `Block`.
+ validate_array_init_ptr,
/// A struct literal with a specified type, with no fields.
/// Uses the `un_node` field.
struct_init_empty,
@@ -690,6 +694,18 @@ pub const Inst = struct {
/// Struct initialization without a type.
/// Uses the `pl_node` field. Payload is `StructInitAnon`.
struct_init_anon,
+ /// Array initialization syntax.
+ /// Uses the `pl_node` field. Payload is `MultiOp`.
+ array_init,
+ /// Anonymous array initialization syntax.
+ /// Uses the `pl_node` field. Payload is `MultiOp`.
+ array_init_anon,
+ /// Array initialization syntax, make the result a pointer.
+ /// Uses the `pl_node` field. Payload is `MultiOp`.
+ array_init_ref,
+ /// Anonymous array initialization syntax, make the result a pointer.
+ /// Uses the `pl_node` field. Payload is `MultiOp`.
+ array_init_anon_ref,
/// Given a pointer to a union and a comptime known field name, activates that field
/// and returns a pointer to it.
/// Uses the `pl_node` field. Payload is `UnionInitPtr`.
@@ -700,14 +716,8 @@ pub const Inst = struct {
size_of,
/// Implements the `@bitSizeOf` builtin. Uses `un_node`.
bit_size_of,
- /// Implements the `@This` builtin. Uses `node`.
- this,
- /// Implements the `@fence` builtin. Uses `un_node`.
+ /// Implements the `@fence` builtin. Uses `node`.
fence,
- /// Implements the `@returnAddress` builtin. Uses `un_node`.
- ret_addr,
- /// Implements the `@src` builtin. Uses `un_node`.
- builtin_src,
/// Implements the `@addWithOverflow` builtin. Uses `pl_node` with `OverflowArithmetic`.
add_with_overflow,
/// Implements the `@subWithOverflow` builtin. Uses `pl_node` with `OverflowArithmetic`.
@@ -717,16 +727,6 @@ pub const Inst = struct {
/// Implements the `@shlWithOverflow` builtin. Uses `pl_node` with `OverflowArithmetic`.
shl_with_overflow,
- /// Implements the `@errorReturnTrace` builtin.
- /// Uses the `un_node` field.
- error_return_trace,
- /// Implements the `@frame` builtin.
- /// Uses the `un_node` field.
- frame,
- /// Implements the `@frameAddress` builtin.
- /// Uses the `un_node` field.
- frame_address,
-
/// Implement builtin `@ptrToInt`. Uses `un_node`.
ptr_to_int,
/// Implement builtin `@errToInt`. Uses `un_node`.
@@ -951,6 +951,7 @@ pub const Inst = struct {
.array_mul,
.array_type,
.array_type_sentinel,
+ .elem_type,
.indexable_ptr_len,
.as,
.as_node,
@@ -970,6 +971,7 @@ pub const Inst = struct {
.bool_and,
.bool_or,
.breakpoint,
+ .fence,
.call,
.call_chkused,
.call_compile_time,
@@ -1026,8 +1028,6 @@ pub const Inst = struct {
.param_type,
.ptrtoint,
.ref,
- .ret_ptr,
- .ret_type,
.shl,
.shr,
.store,
@@ -1094,9 +1094,14 @@ pub const Inst = struct {
.switch_block_ref_under,
.switch_block_ref_under_multi,
.validate_struct_init_ptr,
+ .validate_array_init_ptr,
.struct_init_empty,
.struct_init,
.struct_init_anon,
+ .array_init,
+ .array_init_anon,
+ .array_init_ref,
+ .array_init_anon_ref,
.union_init_ptr,
.field_type,
.field_type_ref,
@@ -1105,17 +1110,10 @@ pub const Inst = struct {
.type_info,
.size_of,
.bit_size_of,
- .this,
- .fence,
- .ret_addr,
- .builtin_src,
.add_with_overflow,
.sub_with_overflow,
.mul_with_overflow,
.shl_with_overflow,
- .error_return_trace,
- .frame,
- .frame_address,
.ptr_to_int,
.align_of,
.bool_to_int,
@@ -1211,6 +1209,30 @@ pub const Inst = struct {
/// `operand` is payload index to `ExtendedFunc`.
/// `small` is `ExtendedFunc.Small`.
func,
+ /// Obtains a pointer to the return value.
+ /// `operand` is `src_node: i32`.
+ ret_ptr,
+ /// Obtains the return type of the in-scope function.
+ /// `operand` is `src_node: i32`.
+ ret_type,
+ /// Implements the `@This` builtin.
+ /// `operand` is `src_node: i32`.
+ this,
+ /// Implements the `@returnAddress` builtin.
+ /// `operand` is `src_node: i32`.
+ ret_addr,
+ /// Implements the `@src` builtin.
+ /// `operand` is `src_node: i32`.
+ builtin_src,
+ /// Implements the `@errorReturnTrace` builtin.
+ /// `operand` is `src_node: i32`.
+ error_return_trace,
+ /// Implements the `@frame` builtin.
+ /// `operand` is `src_node: i32`.
+ frame,
+ /// Implements the `@frameAddress` builtin.
+ /// `operand` is `src_node: i32`.
+ frame_address,
/// `operand` is payload index to `UnNode`.
c_undef,
/// `operand` is payload index to `UnNode`.
@@ -2281,6 +2303,7 @@ const Writer = struct {
.pop_count,
.byte_swap,
.bit_reverse,
+ .elem_type,
=> try self.writeUnNode(stream, inst),
.ref,
@@ -2317,6 +2340,10 @@ const Writer = struct {
.union_decl,
.struct_init,
.struct_init_anon,
+ .array_init,
+ .array_init_anon,
+ .array_init_ref,
+ .array_init_anon_ref,
.union_init_ptr,
.field_type,
.field_type_ref,
@@ -2409,6 +2436,7 @@ const Writer = struct {
.block_inline_var,
.loop,
.validate_struct_init_ptr,
+ .validate_array_init_ptr,
.c_import,
=> try self.writePlNodeBlock(stream, inst),
@@ -2450,21 +2478,13 @@ const Writer = struct {
.as_node => try self.writeAs(stream, inst),
.breakpoint,
+ .fence,
.opaque_decl,
.dbg_stmt_node,
- .ret_ptr,
- .ret_type,
.repeat,
.repeat_inline,
.alloc_inferred,
.alloc_inferred_mut,
- .this,
- .fence,
- .ret_addr,
- .builtin_src,
- .error_return_trace,
- .frame,
- .frame_address,
=> try self.writeNode(stream, inst),
.error_value,