aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/AstGen.zig897
-rw-r--r--src/Module.zig48
-rw-r--r--src/Sema.zig849
-rw-r--r--src/Zir.zig573
-rw-r--r--src/type.zig188
-rw-r--r--src/value.zig58
6 files changed, 2185 insertions, 428 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig
index 68e8fcc42e..d7c379c0a0 100644
--- a/src/AstGen.zig
+++ b/src/AstGen.zig
@@ -51,6 +51,7 @@ pub fn addExtraAssumeCapacity(astgen: *AstGen, extra: anytype) u32 {
astgen.extra.appendAssumeCapacity(switch (field.field_type) {
u32 => @field(extra, field.name),
Zir.Inst.Ref => @enumToInt(@field(extra, field.name)),
+ i32 => @bitCast(u32, @field(extra, field.name)),
else => @compileError("bad field type"),
});
}
@@ -237,6 +238,9 @@ pub const ResultLoc = union(enum) {
}
};
+pub const align_rl: ResultLoc = .{ .ty = .u16_type };
+pub const bool_rl: ResultLoc = .{ .ty = .bool_type };
+
pub fn typeExpr(gz: *GenZir, scope: *Scope, type_node: ast.Node.Index) InnerError!Zir.Inst.Ref {
return expr(gz, scope, .{ .ty = .type_type }, type_node);
}
@@ -469,20 +473,22 @@ pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inn
try assign(gz, scope, node);
return rvalue(gz, scope, rl, .void_value, node);
},
- .assign_bit_and => {
- try assignOp(gz, scope, node, .bit_and);
+
+ .assign_bit_shift_left => {
+ try assignShift(gz, scope, node, .shl);
return rvalue(gz, scope, rl, .void_value, node);
},
- .assign_bit_or => {
- try assignOp(gz, scope, node, .bit_or);
+ .assign_bit_shift_right => {
+ try assignShift(gz, scope, node, .shr);
return rvalue(gz, scope, rl, .void_value, node);
},
- .assign_bit_shift_left => {
- try assignOp(gz, scope, node, .shl);
+
+ .assign_bit_and => {
+ try assignOp(gz, scope, node, .bit_and);
return rvalue(gz, scope, rl, .void_value, node);
},
- .assign_bit_shift_right => {
- try assignOp(gz, scope, node, .shr);
+ .assign_bit_or => {
+ try assignOp(gz, scope, node, .bit_or);
return rvalue(gz, scope, rl, .void_value, node);
},
.assign_bit_xor => {
@@ -522,51 +528,54 @@ pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inn
return rvalue(gz, scope, rl, .void_value, node);
},
- .add => return simpleBinOp(gz, scope, rl, node, .add),
+ // zig fmt: off
+ .bit_shift_left => return shiftOp(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .shl),
+ .bit_shift_right => return shiftOp(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .shr),
+
+ .add => return simpleBinOp(gz, scope, rl, node, .add),
.add_wrap => return simpleBinOp(gz, scope, rl, node, .addwrap),
- .sub => return simpleBinOp(gz, scope, rl, node, .sub),
+ .sub => return simpleBinOp(gz, scope, rl, node, .sub),
.sub_wrap => return simpleBinOp(gz, scope, rl, node, .subwrap),
- .mul => return simpleBinOp(gz, scope, rl, node, .mul),
+ .mul => return simpleBinOp(gz, scope, rl, node, .mul),
.mul_wrap => return simpleBinOp(gz, scope, rl, node, .mulwrap),
- .div => return simpleBinOp(gz, scope, rl, node, .div),
- .mod => return simpleBinOp(gz, scope, rl, node, .mod_rem),
- .bit_and => return simpleBinOp(gz, scope, rl, node, .bit_and),
- .bit_or => return simpleBinOp(gz, scope, rl, node, .bit_or),
- .bit_shift_left => return simpleBinOp(gz, scope, rl, node, .shl),
- .bit_shift_right => return simpleBinOp(gz, scope, rl, node, .shr),
- .bit_xor => return simpleBinOp(gz, scope, rl, node, .xor),
-
- .bang_equal => return simpleBinOp(gz, scope, rl, node, .cmp_neq),
- .equal_equal => return simpleBinOp(gz, scope, rl, node, .cmp_eq),
- .greater_than => return simpleBinOp(gz, scope, rl, node, .cmp_gt),
+ .div => return simpleBinOp(gz, scope, rl, node, .div),
+ .mod => return simpleBinOp(gz, scope, rl, node, .mod_rem),
+ .bit_and => return simpleBinOp(gz, scope, rl, node, .bit_and),
+ .bit_or => return simpleBinOp(gz, scope, rl, node, .bit_or),
+ .bit_xor => return simpleBinOp(gz, scope, rl, node, .xor),
+
+ .bang_equal => return simpleBinOp(gz, scope, rl, node, .cmp_neq),
+ .equal_equal => return simpleBinOp(gz, scope, rl, node, .cmp_eq),
+ .greater_than => return simpleBinOp(gz, scope, rl, node, .cmp_gt),
.greater_or_equal => return simpleBinOp(gz, scope, rl, node, .cmp_gte),
- .less_than => return simpleBinOp(gz, scope, rl, node, .cmp_lt),
- .less_or_equal => return simpleBinOp(gz, scope, rl, node, .cmp_lte),
+ .less_than => return simpleBinOp(gz, scope, rl, node, .cmp_lt),
+ .less_or_equal => return simpleBinOp(gz, scope, rl, node, .cmp_lte),
- .array_cat => return simpleBinOp(gz, scope, rl, node, .array_cat),
- .array_mult => return simpleBinOp(gz, scope, rl, node, .array_mul),
+ .array_cat => return simpleBinOp(gz, scope, rl, node, .array_cat),
+ .array_mult => return simpleBinOp(gz, scope, rl, node, .array_mul),
- .error_union => return simpleBinOp(gz, scope, rl, node, .error_union_type),
+ .error_union => return simpleBinOp(gz, scope, rl, node, .error_union_type),
.merge_error_sets => return simpleBinOp(gz, scope, rl, node, .merge_error_sets),
.bool_and => return boolBinOp(gz, scope, rl, node, .bool_br_and),
- .bool_or => return boolBinOp(gz, scope, rl, node, .bool_br_or),
+ .bool_or => return boolBinOp(gz, scope, rl, node, .bool_br_or),
.bool_not => return boolNot(gz, scope, rl, node),
- .bit_not => return bitNot(gz, scope, rl, node),
+ .bit_not => return bitNot(gz, scope, rl, node),
- .negation => return negation(gz, scope, rl, node, .negate),
+ .negation => return negation(gz, scope, rl, node, .negate),
.negation_wrap => return negation(gz, scope, rl, node, .negate_wrap),
.identifier => return identifier(gz, scope, rl, node),
.asm_simple => return asmExpr(gz, scope, rl, node, tree.asmSimple(node)),
- .@"asm" => return asmExpr(gz, scope, rl, node, tree.asmFull(node)),
+ .@"asm" => return asmExpr(gz, scope, rl, node, tree.asmFull(node)),
- .string_literal => return stringLiteral(gz, scope, rl, node),
+ .string_literal => return stringLiteral(gz, scope, rl, node),
.multiline_string_literal => return multilineStringLiteral(gz, scope, rl, node),
.integer_literal => return integerLiteral(gz, scope, rl, node),
+ // zig fmt: on
.builtin_call_two, .builtin_call_two_comma => {
if (node_datas[node].lhs == 0) {
@@ -1181,13 +1190,14 @@ fn labeledBlockExpr(
// All break operands are values that did not use the result location pointer.
if (strat.elide_store_to_block_ptr_instructions) {
for (block_scope.labeled_store_to_block_ptr_list.items) |inst| {
- zir_tags[inst] = .elided;
- zir_datas[inst] = undefined;
+ // Mark as elided for removal below.
+ assert(zir_tags[inst] == .store_to_block_ptr);
+ zir_datas[inst].bin.lhs = .none;
}
- // TODO technically not needed since we changed the tag to elided but
- // would be better still to elide the ones that are in this list.
+ try block_scope.setBlockBodyEliding(block_inst);
+ } else {
+ try block_scope.setBlockBody(block_inst);
}
- try block_scope.setBlockBody(block_inst);
const block_ref = gz.indexToRef(block_inst);
switch (rl) {
.ref => return block_ref,
@@ -1222,20 +1232,24 @@ fn blockExprStmts(
.simple_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.simpleVarDecl(statement)),
.aligned_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.alignedVarDecl(statement)),
+ // zig fmt: off
.assign => try assign(gz, scope, statement),
- .assign_bit_and => try assignOp(gz, scope, statement, .bit_and),
- .assign_bit_or => try assignOp(gz, scope, statement, .bit_or),
- .assign_bit_shift_left => try assignOp(gz, scope, statement, .shl),
- .assign_bit_shift_right => try assignOp(gz, scope, statement, .shr),
- .assign_bit_xor => try assignOp(gz, scope, statement, .xor),
- .assign_div => try assignOp(gz, scope, statement, .div),
- .assign_sub => try assignOp(gz, scope, statement, .sub),
+
+ .assign_bit_shift_left => try assignShift(gz, scope, statement, .shl),
+ .assign_bit_shift_right => try assignShift(gz, scope, statement, .shr),
+
+ .assign_bit_and => try assignOp(gz, scope, statement, .bit_and),
+ .assign_bit_or => try assignOp(gz, scope, statement, .bit_or),
+ .assign_bit_xor => try assignOp(gz, scope, statement, .xor),
+ .assign_div => try assignOp(gz, scope, statement, .div),
+ .assign_sub => try assignOp(gz, scope, statement, .sub),
.assign_sub_wrap => try assignOp(gz, scope, statement, .subwrap),
- .assign_mod => try assignOp(gz, scope, statement, .mod_rem),
- .assign_add => try assignOp(gz, scope, statement, .add),
+ .assign_mod => try assignOp(gz, scope, statement, .mod_rem),
+ .assign_add => try assignOp(gz, scope, statement, .add),
.assign_add_wrap => try assignOp(gz, scope, statement, .addwrap),
- .assign_mul => try assignOp(gz, scope, statement, .mul),
+ .assign_mul => try assignOp(gz, scope, statement, .mul),
.assign_mul_wrap => try assignOp(gz, scope, statement, .mulwrap),
+ // zig fmt: on
else => {
// We need to emit an error if the result is not `noreturn` or `void`, but
@@ -1313,7 +1327,6 @@ fn blockExprStmts(
.func_var_args,
.func_extra,
.func_extra_var_args,
- .has_decl,
.int,
.float,
.float128,
@@ -1390,6 +1403,7 @@ fn blockExprStmts(
.switch_capture_else_ref,
.struct_init_empty,
.struct_init,
+ .union_init_ptr,
.field_type,
.struct_decl,
.struct_decl_packed,
@@ -1404,7 +1418,6 @@ fn blockExprStmts(
.size_of,
.bit_size_of,
.this,
- .fence,
.ret_addr,
.builtin_src,
.add_with_overflow,
@@ -1412,10 +1425,80 @@ fn blockExprStmts(
.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,
+ .embed_file,
+ .error_name,
+ .sqrt,
+ .sin,
+ .cos,
+ .exp,
+ .exp2,
+ .log,
+ .log2,
+ .log10,
+ .fabs,
+ .floor,
+ .ceil,
+ .trunc,
+ .round,
+ .tag_name,
+ .reify,
+ .type_name,
+ .frame_type,
+ .frame_size,
+ .float_to_int,
+ .int_to_float,
+ .int_to_ptr,
+ .float_cast,
+ .int_cast,
+ .err_set_cast,
+ .ptr_cast,
+ .truncate,
+ .align_cast,
+ .has_decl,
+ .has_field,
+ .clz,
+ .ctz,
+ .pop_count,
+ .byte_swap,
+ .bit_reverse,
+ .div_exact,
+ .div_floor,
+ .div_trunc,
+ .mod,
+ .rem,
+ .shl_exact,
+ .shr_exact,
+ .bit_offset_of,
+ .byte_offset_of,
+ .cmpxchg_strong,
+ .cmpxchg_weak,
+ .splat,
+ .reduce,
+ .shuffle,
+ .atomic_load,
+ .atomic_rmw,
+ .atomic_store,
+ .mul_add,
+ .builtin_call,
+ .field_ptr_type,
+ .field_parent_ptr,
+ .memcpy,
+ .memset,
+ .builtin_async_call,
+ .c_import,
+ .extended,
=> break :b false,
// ZIR instructions that are always either `noreturn` or `void`.
.breakpoint,
+ .fence,
.dbg_stmt_node,
.ensure_result_used,
.ensure_result_non_error,
@@ -1432,7 +1515,6 @@ fn blockExprStmts(
.ret_tok,
.ret_coerce,
.@"unreachable",
- .elided,
.store,
.store_node,
.store_to_block_ptr,
@@ -1441,6 +1523,11 @@ fn blockExprStmts(
.repeat,
.repeat_inline,
.validate_struct_init_ptr,
+ .panic,
+ .set_align_stack,
+ .set_cold,
+ .set_float_mode,
+ .set_runtime_safety,
=> break :b true,
}
} else switch (maybe_unused_result) {
@@ -1702,12 +1789,34 @@ fn assignOp(
_ = try gz.addBin(.store, lhs_ptr, result);
}
+fn assignShift(
+ gz: *GenZir,
+ scope: *Scope,
+ infix_node: ast.Node.Index,
+ op_inst_tag: Zir.Inst.Tag,
+) InnerError!void {
+ const astgen = gz.astgen;
+ const tree = &astgen.file.tree;
+ const node_datas = tree.nodes.items(.data);
+
+ const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs);
+ const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node);
+ const rhs_type = try gz.addUnNode(.typeof_log2_int_type, lhs, infix_node);
+ const rhs = try expr(gz, scope, .{ .ty = rhs_type }, node_datas[infix_node].rhs);
+
+ const result = try gz.addPlNode(op_inst_tag, infix_node, Zir.Inst.Bin{
+ .lhs = lhs,
+ .rhs = rhs,
+ });
+ _ = try gz.addBin(.store, lhs_ptr, result);
+}
+
fn boolNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref {
const astgen = gz.astgen;
const tree = &astgen.file.tree;
const node_datas = tree.nodes.items(.data);
- const operand = try expr(gz, scope, .{ .ty = .bool_type }, node_datas[node].lhs);
+ const operand = try expr(gz, scope, bool_rl, node_datas[node].lhs);
const result = try gz.addUnNode(.bool_not, operand, node);
return rvalue(gz, scope, rl, result, node);
}
@@ -1778,7 +1887,7 @@ fn ptrType(
trailing_count += 1;
}
if (ptr_info.ast.align_node != 0) {
- align_ref = try expr(gz, scope, .none, ptr_info.ast.align_node);
+ align_ref = try expr(gz, scope, align_rl, ptr_info.ast.align_node);
trailing_count += 1;
}
if (ptr_info.ast.bit_range_start != 0) {
@@ -1978,19 +2087,16 @@ fn fnDecl(
);
const cc: Zir.Inst.Ref = if (fn_proto.ast.callconv_expr != 0)
- // TODO instead of enum literal type, this needs to be the
- // std.builtin.CallingConvention enum. We need to implement importing other files
- // and enums in order to fix this.
try AstGen.expr(
&decl_gz,
&decl_gz.base,
- .{ .ty = .enum_literal_type },
+ .{ .ty = .calling_convention_type },
fn_proto.ast.callconv_expr,
)
else if (is_extern) // note: https://github.com/ziglang/zig/issues/5269
- try decl_gz.addSmallStr(.enum_literal_small, "C")
+ Zir.Inst.Ref.calling_convention_c
else
- .none;
+ Zir.Inst.Ref.none;
const func_inst: Zir.Inst.Ref = if (body_node == 0) func: {
if (is_extern) {
@@ -3079,7 +3185,7 @@ fn boolBinOp(
) InnerError!Zir.Inst.Ref {
const node_datas = gz.tree().nodes.items(.data);
- const lhs = try expr(gz, scope, .{ .ty = .bool_type }, node_datas[node].lhs);
+ const lhs = try expr(gz, scope, bool_rl, node_datas[node].lhs);
const bool_br = try gz.addBoolBr(zir_tag, lhs);
var rhs_scope: GenZir = .{
@@ -3089,7 +3195,7 @@ fn boolBinOp(
.force_comptime = gz.force_comptime,
};
defer rhs_scope.instructions.deinit(gz.astgen.gpa);
- const rhs = try expr(&rhs_scope, &rhs_scope.base, .{ .ty = .bool_type }, node_datas[node].rhs);
+ const rhs = try expr(&rhs_scope, &rhs_scope.base, bool_rl, node_datas[node].rhs);
_ = try rhs_scope.addBreak(.break_inline, bool_br, rhs);
try rhs_scope.setBoolBrBody(bool_br);
@@ -3122,7 +3228,7 @@ fn ifExpr(
} else if (if_full.payload_token) |payload_token| {
return astgen.failTok(payload_token, "TODO implement if optional", .{});
} else {
- break :c try expr(&block_scope, &block_scope.base, .{ .ty = .bool_type }, if_full.ast.cond_expr);
+ break :c try expr(&block_scope, &block_scope.base, bool_rl, if_full.ast.cond_expr);
}
};
@@ -3291,8 +3397,7 @@ fn whileExpr(
} else if (while_full.payload_token) |payload_token| {
return astgen.failTok(payload_token, "TODO implement while optional", .{});
} else {
- const bool_type_rl: ResultLoc = .{ .ty = .bool_type };
- break :c try expr(&continue_scope, &continue_scope.base, bool_type_rl, while_full.ast.cond_expr);
+ break :c try expr(&continue_scope, &continue_scope.base, bool_rl, while_full.ast.cond_expr);
}
};
@@ -4758,37 +4863,8 @@ fn builtinCall(
}
}
+ // zig fmt: off
switch (info.tag) {
- .ptr_to_int => {
- const operand = try expr(gz, scope, .none, params[0]);
- const result = try gz.addUnNode(.ptrtoint, operand, node);
- return rvalue(gz, scope, rl, result, node);
- },
- .float_cast => {
- const dest_type = try typeExpr(gz, scope, params[0]);
- const rhs = try expr(gz, scope, .none, params[1]);
- const result = try gz.addPlNode(.floatcast, node, Zir.Inst.Bin{
- .lhs = dest_type,
- .rhs = rhs,
- });
- return rvalue(gz, scope, rl, result, node);
- },
- .int_cast => {
- const dest_type = try typeExpr(gz, scope, params[0]);
- const rhs = try expr(gz, scope, .none, params[1]);
- const result = try gz.addPlNode(.intcast, node, Zir.Inst.Bin{
- .lhs = dest_type,
- .rhs = rhs,
- });
- return rvalue(gz, scope, rl, result, node);
- },
- .breakpoint => {
- _ = try gz.add(.{
- .tag = .breakpoint,
- .data = .{ .node = gz.nodeIndexToRelative(node) },
- });
- return rvalue(gz, scope, rl, .void_value, node);
- },
.import => {
const node_tags = tree.nodes.items(.tag);
const node_datas = tree.nodes.items(.data);
@@ -4804,26 +4880,6 @@ fn builtinCall(
const result = try gz.addStrTok(.import, str.index, str_lit_token);
return rvalue(gz, scope, rl, result, node);
},
- .error_to_int => {
- const target = try expr(gz, scope, .none, params[0]);
- const result = try gz.addUnNode(.error_to_int, target, node);
- return rvalue(gz, scope, rl, result, node);
- },
- .int_to_error => {
- const target = try expr(gz, scope, .{ .ty = .u16_type }, params[0]);
- const result = try gz.addUnNode(.int_to_error, target, node);
- return rvalue(gz, scope, rl, result, node);
- },
- .compile_error => {
- const target = try expr(gz, scope, .none, params[0]);
- const result = try gz.addUnNode(.compile_error, target, node);
- return rvalue(gz, scope, rl, result, node);
- },
- .set_eval_branch_quota => {
- const quota = try expr(gz, scope, .{ .ty = .u32_type }, params[0]);
- const result = try gz.addUnNode(.set_eval_branch_quota, quota, node);
- return rvalue(gz, scope, rl, result, node);
- },
.compile_log => {
const arg_refs = try astgen.gpa.alloc(Zir.Inst.Ref, params.len);
defer astgen.gpa.free(arg_refs);
@@ -4850,23 +4906,11 @@ fn builtinCall(
});
return rvalue(gz, scope, rl, result, node);
},
- .as => return as(gz, scope, rl, node, params[0], params[1]),
- .bit_cast => return bitCast(gz, scope, rl, node, params[0], params[1]),
- .TypeOf => return typeOf(gz, scope, rl, node, params),
-
- .int_to_enum => {
- const result = try gz.addPlNode(.int_to_enum, node, Zir.Inst.Bin{
- .lhs = try typeExpr(gz, scope, params[0]),
- .rhs = try expr(gz, scope, .none, params[1]),
- });
- return rvalue(gz, scope, rl, result, node);
- },
-
- .enum_to_int => {
- const operand = try expr(gz, scope, .none, params[0]);
- const result = try gz.addUnNode(.enum_to_int, operand, node);
- return rvalue(gz, scope, rl, result, node);
- },
+ .as => return as( gz, scope, rl, node, params[0], params[1]),
+ .bit_cast => return bitCast( gz, scope, rl, node, params[0], params[1]),
+ .TypeOf => return typeOf( gz, scope, rl, node, params),
+ .union_init => return unionInit(gz, scope, rl, node, params),
+ .c_import => return cImport( gz, scope, rl, node, params[0]),
.@"export" => {
// TODO: @export is supposed to be able to export things other than functions.
@@ -4882,38 +4926,147 @@ fn builtinCall(
return rvalue(gz, scope, rl, .void_value, node);
},
- .has_decl => {
- const container_type = try typeExpr(gz, scope, params[0]);
- const name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]);
- const result = try gz.addPlNode(.has_decl, node, Zir.Inst.Bin{
- .lhs = container_type,
- .rhs = name,
+ .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),
+
+ .type_info => return simpleUnOpType(gz, scope, rl, node, params[0], .type_info),
+ .size_of => return simpleUnOpType(gz, scope, rl, node, params[0], .size_of),
+ .bit_size_of => return simpleUnOpType(gz, scope, rl, node, params[0], .bit_size_of),
+ .align_of => return simpleUnOpType(gz, scope, rl, node, params[0], .align_of),
+
+ .ptr_to_int => return simpleUnOp(gz, scope, rl, node, .none, params[0], .ptr_to_int),
+ .error_to_int => return simpleUnOp(gz, scope, rl, node, .none, params[0], .error_to_int),
+ .int_to_error => return simpleUnOp(gz, scope, rl, node, .{ .ty = .u16_type }, params[0], .int_to_error),
+ .compile_error => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], .compile_error),
+ .set_eval_branch_quota => return simpleUnOp(gz, scope, rl, node, .{ .ty = .u32_type }, params[0], .set_eval_branch_quota),
+ .enum_to_int => return simpleUnOp(gz, scope, rl, node, .none, params[0], .enum_to_int),
+ .bool_to_int => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .bool_to_int),
+ .embed_file => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], .embed_file),
+ .error_name => return simpleUnOp(gz, scope, rl, node, .{ .ty = .anyerror_type }, params[0], .error_name),
+ .panic => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], .panic),
+ .set_align_stack => return simpleUnOp(gz, scope, rl, node, align_rl, params[0], .set_align_stack),
+ .set_cold => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .set_cold),
+ .set_float_mode => return simpleUnOp(gz, scope, rl, node, .{ .ty = .float_mode_type }, params[0], .set_float_mode),
+ .set_runtime_safety => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .set_runtime_safety),
+ .sqrt => return simpleUnOp(gz, scope, rl, node, .none, params[0], .sqrt),
+ .sin => return simpleUnOp(gz, scope, rl, node, .none, params[0], .sin),
+ .cos => return simpleUnOp(gz, scope, rl, node, .none, params[0], .cos),
+ .exp => return simpleUnOp(gz, scope, rl, node, .none, params[0], .exp),
+ .exp2 => return simpleUnOp(gz, scope, rl, node, .none, params[0], .exp2),
+ .log => return simpleUnOp(gz, scope, rl, node, .none, params[0], .log),
+ .log2 => return simpleUnOp(gz, scope, rl, node, .none, params[0], .log2),
+ .log10 => return simpleUnOp(gz, scope, rl, node, .none, params[0], .log10),
+ .fabs => return simpleUnOp(gz, scope, rl, node, .none, params[0], .fabs),
+ .floor => return simpleUnOp(gz, scope, rl, node, .none, params[0], .floor),
+ .ceil => return simpleUnOp(gz, scope, rl, node, .none, params[0], .ceil),
+ .trunc => return simpleUnOp(gz, scope, rl, node, .none, params[0], .trunc),
+ .round => return simpleUnOp(gz, scope, rl, node, .none, params[0], .round),
+ .tag_name => return simpleUnOp(gz, scope, rl, node, .none, params[0], .tag_name),
+ .Type => return simpleUnOp(gz, scope, rl, node, .none, params[0], .reify),
+ .type_name => return simpleUnOp(gz, scope, rl, node, .none, params[0], .type_name),
+ .Frame => return simpleUnOp(gz, scope, rl, node, .none, params[0], .frame_type),
+ .frame_size => return simpleUnOp(gz, scope, rl, node, .none, params[0], .frame_size),
+
+ .float_to_int => return typeCast(gz, scope, rl, node, params[0], params[1], .float_to_int),
+ .int_to_float => return typeCast(gz, scope, rl, node, params[0], params[1], .int_to_float),
+ .int_to_ptr => return typeCast(gz, scope, rl, node, params[0], params[1], .int_to_ptr),
+ .int_to_enum => return typeCast(gz, scope, rl, node, params[0], params[1], .int_to_enum),
+ .float_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .float_cast),
+ .int_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .int_cast),
+ .err_set_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .err_set_cast),
+ .ptr_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .ptr_cast),
+ .truncate => return typeCast(gz, scope, rl, node, params[0], params[1], .truncate),
+ .align_cast => {
+ const dest_align = try comptimeExpr(gz, scope, align_rl, params[0]);
+ const rhs = try expr(gz, scope, .none, params[1]);
+ const result = try gz.addPlNode(.align_cast, node, Zir.Inst.Bin{
+ .lhs = dest_align,
+ .rhs = rhs,
});
return rvalue(gz, scope, rl, result, node);
},
- .type_info => {
- const operand = try typeExpr(gz, scope, params[0]);
- const result = try gz.addUnNode(.type_info, operand, node);
+ .has_decl => return hasDeclOrField(gz, scope, rl, node, params[0], params[1], .has_decl),
+ .has_field => return hasDeclOrField(gz, scope, rl, node, params[0], params[1], .has_field),
+
+ .clz => return bitBuiltin(gz, scope, rl, node, params[0], params[1], .clz),
+ .ctz => return bitBuiltin(gz, scope, rl, node, params[0], params[1], .ctz),
+ .pop_count => return bitBuiltin(gz, scope, rl, node, params[0], params[1], .pop_count),
+ .byte_swap => return bitBuiltin(gz, scope, rl, node, params[0], params[1], .byte_swap),
+ .bit_reverse => return bitBuiltin(gz, scope, rl, node, params[0], params[1], .bit_reverse),
+
+ .div_exact => return divBuiltin(gz, scope, rl, node, params[0], params[1], .div_exact),
+ .div_floor => return divBuiltin(gz, scope, rl, node, params[0], params[1], .div_floor),
+ .div_trunc => return divBuiltin(gz, scope, rl, node, params[0], params[1], .div_trunc),
+ .mod => return divBuiltin(gz, scope, rl, node, params[0], params[1], .mod),
+ .rem => return divBuiltin(gz, scope, rl, node, params[0], params[1], .rem),
+
+ .shl_exact => return shiftOp(gz, scope, rl, node, params[0], params[1], .shl_exact),
+ .shr_exact => return shiftOp(gz, scope, rl, node, params[0], params[1], .shr_exact),
+
+ .bit_offset_of => return offsetOf(gz, scope, rl, node, params[0], params[1], .bit_offset_of),
+ .byte_offset_of => return offsetOf(gz, scope, rl, node, params[0], params[1], .byte_offset_of),
+
+ .c_undef => return simpleCBuiltin(gz, scope, rl, node, params[0], .c_undef),
+ .c_include => return simpleCBuiltin(gz, scope, rl, node, params[0], .c_include),
+
+ .cmpxchg_strong => return cmpxchg(gz, scope, rl, node, params, .cmpxchg_strong),
+ .cmpxchg_weak => return cmpxchg(gz, scope, rl, node, params, .cmpxchg_weak),
+
+ .wasm_memory_size => {
+ const operand = try expr(gz, scope, .{ .ty = .u32_type }, params[0]);
+ const result = try gz.addExtendedPayload(.wasm_memory_size, Zir.Inst.UnNode{
+ .node = gz.nodeIndexToRelative(node),
+ .operand = operand,
+ });
return rvalue(gz, scope, rl, result, node);
},
-
- .size_of => {
- const operand = try typeExpr(gz, scope, params[0]);
- const result = try gz.addUnNode(.size_of, operand, node);
+ .wasm_memory_grow => {
+ const index_arg = try expr(gz, scope, .{ .ty = .u32_type }, params[0]);
+ const delta_arg = try expr(gz, scope, .{ .ty = .u32_type }, params[1]);
+ const result = try gz.addExtendedPayload(.wasm_memory_grow, Zir.Inst.BinNode{
+ .node = gz.nodeIndexToRelative(node),
+ .lhs = index_arg,
+ .rhs = delta_arg,
+ });
return rvalue(gz, scope, rl, result, node);
},
-
- .bit_size_of => {
- const operand = try typeExpr(gz, scope, params[0]);
- const result = try gz.addUnNode(.bit_size_of, operand, node);
+ .c_define => {
+ const name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[0]);
+ const value = try comptimeExpr(gz, scope, .none, params[1]);
+ const result = try gz.addExtendedPayload(.c_define, Zir.Inst.BinNode{
+ .node = gz.nodeIndexToRelative(node),
+ .lhs = name,
+ .rhs = value,
+ });
return rvalue(gz, scope, rl, result, node);
},
- .This => return rvalue(gz, scope, rl, try gz.addNode(.this, node), node),
- .fence => return rvalue(gz, scope, rl, try gz.addNode(.fence, 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),
+ .splat => {
+ const len = try expr(gz, scope, .{ .ty = .u32_type }, params[0]);
+ const scalar = try expr(gz, scope, .none, params[1]);
+ const result = try gz.addPlNode(.splat, node, Zir.Inst.Bin{
+ .lhs = len,
+ .rhs = scalar,
+ });
+ return rvalue(gz, scope, rl, result, node);
+ },
+ .reduce => {
+ const op = try expr(gz, scope, .{ .ty = .reduce_op_type }, params[0]);
+ const scalar = try expr(gz, scope, .none, params[1]);
+ const result = try gz.addPlNode(.reduce, node, Zir.Inst.Bin{
+ .lhs = op,
+ .rhs = scalar,
+ });
+ return rvalue(gz, scope, rl, result, node);
+ },
.add_with_overflow => return overflowArithmetic(gz, scope, rl, node, params, .add_with_overflow),
.sub_with_overflow => return overflowArithmetic(gz, scope, rl, node, params, .sub_with_overflow),
@@ -4941,83 +5094,373 @@ fn builtinCall(
return rvalue(gz, scope, rl, result, node);
},
- .align_cast,
- .align_of,
- .atomic_load,
- .atomic_rmw,
- .atomic_store,
- .bit_offset_of,
- .bool_to_int,
- .mul_add,
- .byte_swap,
- .bit_reverse,
- .byte_offset_of,
- .call,
- .c_define,
- .c_import,
- .c_include,
- .clz,
- .cmpxchg_strong,
- .cmpxchg_weak,
- .ctz,
- .c_undef,
- .div_exact,
- .div_floor,
- .div_trunc,
- .embed_file,
- .error_name,
- .error_return_trace,
- .err_set_cast,
- .field_parent_ptr,
- .float_to_int,
- .has_field,
- .int_to_float,
- .int_to_ptr,
- .memcpy,
- .memset,
- .wasm_memory_size,
- .wasm_memory_grow,
- .mod,
- .panic,
- .pop_count,
- .ptr_cast,
- .rem,
- .set_align_stack,
- .set_cold,
- .set_float_mode,
- .set_runtime_safety,
- .shl_exact,
- .shr_exact,
- .shuffle,
- .splat,
- .reduce,
- .sqrt,
- .sin,
- .cos,
- .exp,
- .exp2,
- .log,
- .log2,
- .log10,
- .fabs,
- .floor,
- .ceil,
- .trunc,
- .round,
- .tag_name,
- .truncate,
- .Type,
- .type_name,
- .union_init,
- .async_call,
- .frame,
- .Frame,
- .frame_address,
- .frame_size,
- => return astgen.failNode(node, "TODO: implement builtin function {s}", .{
- builtin_name,
- }),
+ .atomic_load => {
+ const int_type = try typeExpr(gz, scope, params[0]);
+ const ptr_type = try gz.add(.{ .tag = .ptr_type_simple, .data = .{
+ .ptr_type_simple = .{
+ .is_allowzero = false,
+ .is_mutable = false,
+ .is_volatile = false,
+ .size = .One,
+ .elem_type = int_type,
+ },
+ } });
+ const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[1]);
+ const ordering = try expr(gz, scope, .{ .ty = .atomic_ordering_type }, params[2]);
+ const result = try gz.addPlNode(.atomic_load, node, Zir.Inst.Bin{
+ .lhs = ptr,
+ .rhs = ordering,
+ });
+ return rvalue(gz, scope, rl, result, node);
+ },
+ .atomic_rmw => {
+ const int_type = try typeExpr(gz, scope, params[0]);
+ const ptr_type = try gz.add(.{ .tag = .ptr_type_simple, .data = .{
+ .ptr_type_simple = .{
+ .is_allowzero = false,
+ .is_mutable = true,
+ .is_volatile = false,
+ .size = .One,
+ .elem_type = int_type,
+ },
+ } });
+ const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[1]);
+ const operation = try expr(gz, scope, .{ .ty = .atomic_rmw_op_type }, params[2]);
+ const operand = try expr(gz, scope, .{ .ty = int_type }, params[3]);
+ const ordering = try expr(gz, scope, .{ .ty = .atomic_ordering_type }, params[4]);
+ const result = try gz.addPlNode(.atomic_rmw, node, Zir.Inst.AtomicRmw{
+ .ptr = ptr,
+ .operation = operation,
+ .operand = operand,
+ .ordering = ordering,
+ });
+ return rvalue(gz, scope, rl, result, node);
+ },
+ .atomic_store => {
+ const int_type = try typeExpr(gz, scope, params[0]);
+ const ptr_type = try gz.add(.{ .tag = .ptr_type_simple, .data = .{
+ .ptr_type_simple = .{
+ .is_allowzero = false,
+ .is_mutable = true,
+ .is_volatile = false,
+ .size = .One,
+ .elem_type = int_type,
+ },
+ } });
+ const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[1]);
+ const operand = try expr(gz, scope, .{ .ty = int_type }, params[2]);
+ const ordering = try expr(gz, scope, .{ .ty = .atomic_ordering_type }, params[3]);
+ const result = try gz.addPlNode(.atomic_store, node, Zir.Inst.AtomicStore{
+ .ptr = ptr,
+ .operand = operand,
+ .ordering = ordering,
+ });
+ return rvalue(gz, scope, rl, result, node);
+ },
+ .mul_add => {
+ const float_type = try typeExpr(gz, scope, params[0]);
+ const mulend1 = try expr(gz, scope, .{ .ty = float_type }, params[1]);
+ const mulend2 = try expr(gz, scope, .{ .ty = float_type }, params[2]);
+ const addend = try expr(gz, scope, .{ .ty = float_type }, params[3]);
+ const result = try gz.addPlNode(.mul_add, node, Zir.Inst.MulAdd{
+ .mulend1 = mulend1,
+ .mulend2 = mulend2,
+ .addend = addend,
+ });
+ return rvalue(gz, scope, rl, result, node);
+ },
+ .call => {
+ const options = try comptimeExpr(gz, scope, .{ .ty = .call_options_type }, params[0]);
+ const callee = try expr(gz, scope, .none, params[1]);
+ const args = try expr(gz, scope, .none, params[2]);
+ const result = try gz.addPlNode(.builtin_call, node, Zir.Inst.BuiltinCall{
+ .options = options,
+ .callee = callee,
+ .args = args,
+ });
+ return rvalue(gz, scope, rl, result, node);
+ },
+ .field_parent_ptr => {
+ const parent_type = try typeExpr(gz, scope, params[0]);
+ const field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]);
+ const field_ptr_type = try gz.addBin(.field_ptr_type, parent_type, field_name);
+ const result = try gz.addPlNode(.field_parent_ptr, node, Zir.Inst.FieldParentPtr{
+ .parent_type = parent_type,
+ .field_name = field_name,
+ .field_ptr = try expr(gz, scope, .{ .ty = field_ptr_type }, params[2]),
+ });
+ return rvalue(gz, scope, rl, result, node);
+ },
+ .memcpy => {
+ const result = try gz.addPlNode(.memcpy, node, Zir.Inst.Memcpy{
+ .dest = try expr(gz, scope, .{ .ty = .manyptr_u8_type }, params[0]),
+ .source = try expr(gz, scope, .{ .ty = .manyptr_const_u8_type }, params[1]),
+ .byte_count = try expr(gz, scope, .{ .ty = .usize_type }, params[2]),
+ });
+ return rvalue(gz, scope, rl, result, node);
+ },
+ .memset => {
+ const result = try gz.addPlNode(.memset, node, Zir.Inst.Memset{
+ .dest = try expr(gz, scope, .{ .ty = .manyptr_u8_type }, params[0]),
+ .byte = try expr(gz, scope, .{ .ty = .u8_type }, params[1]),
+ .byte_count = try expr(gz, scope, .{ .ty = .usize_type }, params[2]),
+ });
+ return rvalue(gz, scope, rl, result, node);
+ },
+ .shuffle => {
+ const result = try gz.addPlNode(.shuffle, node, Zir.Inst.Shuffle{
+ .elem_type = try typeExpr(gz, scope, params[0]),
+ .a = try expr(gz, scope, .none, params[1]),
+ .b = try expr(gz, scope, .none, params[2]),
+ .mask = try comptimeExpr(gz, scope, .none, params[3]),
+ });
+ return rvalue(gz, scope, rl, result, node);
+ },
+ .async_call => {
+ const result = try gz.addPlNode(.builtin_async_call, node, Zir.Inst.AsyncCall{
+ .frame_buffer = try expr(gz, scope, .none, params[0]),
+ .result_ptr = try expr(gz, scope, .none, params[1]),
+ .fn_ptr = try expr(gz, scope, .none, params[2]),
+ .args = try expr(gz, scope, .none, params[3]),
+ });
+ return rvalue(gz, scope, rl, result, node);
+ },
}
+ // zig fmt: on
+}
+
+fn simpleNoOpVoid(
+ gz: *GenZir,
+ scope: *Scope,
+ rl: ResultLoc,
+ node: ast.Node.Index,
+ tag: Zir.Inst.Tag,
+) InnerError!Zir.Inst.Ref {
+ _ = try gz.addNode(tag, node);
+ return rvalue(gz, scope, rl, .void_value, node);
+}
+
+fn hasDeclOrField(
+ gz: *GenZir,
+ scope: *Scope,
+ rl: ResultLoc,
+ node: ast.Node.Index,
+ lhs_node: ast.Node.Index,
+ rhs_node: ast.Node.Index,
+ tag: Zir.Inst.Tag,
+) InnerError!Zir.Inst.Ref {
+ const container_type = try typeExpr(gz, scope, lhs_node);
+ const name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, rhs_node);
+ const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{
+ .lhs = container_type,
+ .rhs = name,
+ });
+ return rvalue(gz, scope, rl, result, node);
+}
+
+fn typeCast(
+ gz: *GenZir,
+ scope: *Scope,
+ rl: ResultLoc,
+ node: ast.Node.Index,
+ lhs_node: ast.Node.Index,
+ rhs_node: ast.Node.Index,
+ tag: Zir.Inst.Tag,
+) InnerError!Zir.Inst.Ref {
+ const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{
+ .lhs = try typeExpr(gz, scope, lhs_node),
+ .rhs = try expr(gz, scope, .none, rhs_node),
+ });
+ return rvalue(gz, scope, rl, result, node);
+}
+
+fn simpleUnOpType(
+ gz: *GenZir,
+ scope: *Scope,
+ rl: ResultLoc,
+ node: ast.Node.Index,
+ operand_node: ast.Node.Index,
+ tag: Zir.Inst.Tag,
+) InnerError!Zir.Inst.Ref {
+ const operand = try typeExpr(gz, scope, operand_node);
+ const result = try gz.addUnNode(tag, operand, node);
+ return rvalue(gz, scope, rl, result, node);
+}
+
+fn simpleUnOp(
+ gz: *GenZir,
+ scope: *Scope,
+ rl: ResultLoc,
+ node: ast.Node.Index,
+ operand_rl: ResultLoc,
+ operand_node: ast.Node.Index,
+ tag: Zir.Inst.Tag,
+) InnerError!Zir.Inst.Ref {
+ const operand = try expr(gz, scope, operand_rl, operand_node);
+ const result = try gz.addUnNode(tag, operand, node);
+ return rvalue(gz, scope, rl, result, node);
+}
+
+fn cmpxchg(
+ gz: *GenZir,
+ scope: *Scope,
+ rl: ResultLoc,
+ node: ast.Node.Index,
+ params: []const ast.Node.Index,
+ tag: Zir.Inst.Tag,
+) InnerError!Zir.Inst.Ref {
+ const int_type = try typeExpr(gz, scope, params[0]);
+ const ptr_type = try gz.add(.{ .tag = .ptr_type_simple, .data = .{
+ .ptr_type_simple = .{
+ .is_allowzero = false,
+ .is_mutable = true,
+ .is_volatile = false,
+ .size = .One,
+ .elem_type = int_type,
+ },
+ } });
+ const result = try gz.addPlNode(tag, node, Zir.Inst.Cmpxchg{
+ // zig fmt: off
+ .ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[1]),
+ .expected_value = try expr(gz, scope, .{ .ty = int_type }, params[2]),
+ .new_value = try expr(gz, scope, .{ .ty = int_type }, params[3]),
+ .success_order = try expr(gz, scope, .{ .ty = .atomic_ordering_type }, params[4]),
+ .fail_order = try expr(gz, scope, .{ .ty = .atomic_ordering_type }, params[5]),
+ // zig fmt: on
+ });
+ return rvalue(gz, scope, rl, result, node);
+}
+
+fn bitBuiltin(
+ gz: *GenZir,
+ scope: *Scope,
+ rl: ResultLoc,
+ node: ast.Node.Index,
+ int_type_node: ast.Node.Index,
+ operand_node: ast.Node.Index,
+ tag: Zir.Inst.Tag,
+) InnerError!Zir.Inst.Ref {
+ const int_type = try typeExpr(gz, scope, int_type_node);
+ const operand = try expr(gz, scope, .{ .ty = int_type }, operand_node);
+ const result = try gz.addUnNode(tag, operand, node);
+ return rvalue(gz, scope, rl, result, node);
+}
+
+fn divBuiltin(
+ gz: *GenZir,
+ scope: *Scope,
+ rl: ResultLoc,
+ node: ast.Node.Index,
+ lhs_node: ast.Node.Index,
+ rhs_node: ast.Node.Index,
+ tag: Zir.Inst.Tag,
+) InnerError!Zir.Inst.Ref {
+ const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{
+ .lhs = try expr(gz, scope, .none, lhs_node),
+ .rhs = try expr(gz, scope, .none, rhs_node),
+ });
+ return rvalue(gz, scope, rl, result, node);
+}
+
+fn simpleCBuiltin(
+ gz: *GenZir,
+ scope: *Scope,
+ rl: ResultLoc,
+ node: ast.Node.Index,
+ operand_node: ast.Node.Index,
+ tag: Zir.Inst.Extended,
+) InnerError!Zir.Inst.Ref {
+ const operand = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, operand_node);
+ _ = try gz.addExtendedPayload(tag, Zir.Inst.UnNode{
+ .node = gz.nodeIndexToRelative(node),
+ .operand = operand,
+ });
+ return rvalue(gz, scope, rl, .void_value, node);
+}
+
+fn offsetOf(
+ gz: *GenZir,
+ scope: *Scope,
+ rl: ResultLoc,
+ node: ast.Node.Index,
+ lhs_node: ast.Node.Index,
+ rhs_node: ast.Node.Index,
+ tag: Zir.Inst.Tag,
+) InnerError!Zir.Inst.Ref {
+ const type_inst = try typeExpr(gz, scope, lhs_node);
+ const field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, rhs_node);
+ const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{
+ .lhs = type_inst,
+ .rhs = field_name,
+ });
+ return rvalue(gz, scope, rl, result, node);
+}
+
+fn shiftOp(
+ gz: *GenZir,
+ scope: *Scope,
+ rl: ResultLoc,
+ node: ast.Node.Index,
+ lhs_node: ast.Node.Index,
+ rhs_node: ast.Node.Index,
+ tag: Zir.Inst.Tag,
+) InnerError!Zir.Inst.Ref {
+ const lhs = try expr(gz, scope, .none, lhs_node);
+ const log2_int_type = try gz.addUnNode(.typeof_log2_int_type, lhs, lhs_node);
+ const rhs = try expr(gz, scope, .{ .ty = log2_int_type }, rhs_node);
+ const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{
+ .lhs = lhs,
+ .rhs = rhs,
+ });
+ return rvalue(gz, scope, rl, result, node);
+}
+
+fn cImport(
+ gz: *GenZir,
+ scope: *Scope,
+ rl: ResultLoc,
+ node: ast.Node.Index,
+ body_node: ast.Node.Index,
+) InnerError!Zir.Inst.Ref {
+ const astgen = gz.astgen;
+ const gpa = astgen.gpa;
+
+ var block_scope: GenZir = .{
+ .parent = scope,
+ .decl_node_index = gz.decl_node_index,
+ .astgen = astgen,
+ .force_comptime = true,
+ .instructions = .{},
+ };
+ defer block_scope.instructions.deinit(gpa);
+
+ const block_inst = try gz.addBlock(.c_import, node);
+ const block_result = try expr(&block_scope, &block_scope.base, .none, body_node);
+ if (!gz.refIsNoReturn(block_result)) {
+ _ = try block_scope.addBreak(.break_inline, block_inst, .void_value);
+ }
+ try block_scope.setBlockBody(block_inst);
+ try gz.instructions.append(gpa, block_inst);
+
+ return rvalue(gz, scope, rl, .void_value, node);
+}
+
+fn unionInit(
+ gz: *GenZir,
+ scope: *Scope,
+ rl: ResultLoc,
+ node: ast.Node.Index,
+ params: []const ast.Node.Index,
+) InnerError!Zir.Inst.Ref {
+ const union_type = try typeExpr(gz, scope, params[0]);
+ const field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]);
+ const union_init_ptr = try gz.addPlNode(.union_init_ptr, node, Zir.Inst.UnionInitPtr{
+ .union_type = union_type,
+ .field_name = field_name,
+ });
+ // TODO: set up a store_to_block_ptr elision thing here
+ const result = try expr(gz, scope, .{ .ptr = union_init_ptr }, params[2]);
+ return rvalue(gz, scope, rl, result, node);
}
fn overflowArithmetic(
diff --git a/src/Module.zig b/src/Module.zig
index 7c18f8f65a..bc6d0d4a6c 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -1198,6 +1198,30 @@ pub const Scope = struct {
gz.astgen.extra.appendSliceAssumeCapacity(gz.instructions.items);
}
+ /// Same as `setBlockBody` except we don't copy instructions which are
+ /// `store_to_block_ptr` instructions with lhs set to .none.
+ pub fn setBlockBodyEliding(gz: GenZir, inst: Zir.Inst.Index) !void {
+ const gpa = gz.astgen.gpa;
+ try gz.astgen.extra.ensureCapacity(gpa, gz.astgen.extra.items.len +
+ @typeInfo(Zir.Inst.Block).Struct.fields.len + gz.instructions.items.len);
+ const zir_datas = gz.astgen.instructions.items(.data);
+ const zir_tags = gz.astgen.instructions.items(.tag);
+ const block_pl_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Block{
+ .body_len = @intCast(u32, gz.instructions.items.len),
+ });
+ zir_datas[inst].pl_node.payload_index = block_pl_index;
+ for (gz.instructions.items) |sub_inst| {
+ if (zir_tags[sub_inst] == .store_to_block_ptr and
+ zir_datas[sub_inst].bin.lhs == .none)
+ {
+ // Decrement `body_len`.
+ gz.astgen.extra.items[block_pl_index] -= 1;
+ continue;
+ }
+ gz.astgen.extra.appendAssumeCapacity(sub_inst);
+ }
+ }
+
pub fn identAsString(gz: *GenZir, ident_token: ast.TokenIndex) !u32 {
const astgen = gz.astgen;
const gpa = astgen.gpa;
@@ -1445,6 +1469,30 @@ pub const Scope = struct {
return gz.indexToRef(new_index);
}
+ pub fn addExtendedPayload(
+ gz: *GenZir,
+ opcode: Zir.Inst.Extended,
+ extra: anytype,
+ ) !Zir.Inst.Ref {
+ const gpa = gz.astgen.gpa;
+
+ try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
+ try gz.astgen.instructions.ensureCapacity(gpa, gz.astgen.instructions.len + 1);
+
+ const payload_index = try gz.astgen.addExtra(extra);
+ const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
+ gz.astgen.instructions.appendAssumeCapacity(.{
+ .tag = .extended,
+ .data = .{ .extended = .{
+ .opcode = opcode,
+ .small = undefined,
+ .operand = payload_index,
+ } },
+ });
+ gz.instructions.appendAssumeCapacity(new_index);
+ return gz.indexToRef(new_index);
+ }
+
pub fn addArrayTypeSentinel(
gz: *GenZir,
len: Zir.Inst.Ref,
diff --git a/src/Sema.zig b/src/Sema.zig
index 6fa6174804..38400b72e8 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -131,159 +131,227 @@ pub fn analyzeBody(
while (true) : (i += 1) {
const inst = body[i];
map[inst] = switch (tags[inst]) {
- .elided => continue,
-
- .alloc => try sema.zirAlloc(block, inst),
- .alloc_inferred => try sema.zirAllocInferred(block, inst, Type.initTag(.inferred_alloc_const)),
- .alloc_inferred_mut => try sema.zirAllocInferred(block, inst, Type.initTag(.inferred_alloc_mut)),
- .alloc_mut => try sema.zirAllocMut(block, inst),
- .array_cat => try sema.zirArrayCat(block, inst),
- .array_mul => try sema.zirArrayMul(block, inst),
- .array_type => try sema.zirArrayType(block, inst),
- .array_type_sentinel => try sema.zirArrayTypeSentinel(block, inst),
- .as => try sema.zirAs(block, inst),
- .as_node => try sema.zirAsNode(block, inst),
- .@"asm" => try sema.zirAsm(block, inst, false),
- .asm_volatile => try sema.zirAsm(block, inst, true),
- .bit_and => try sema.zirBitwise(block, inst, .bit_and),
- .bit_not => try sema.zirBitNot(block, inst),
- .bit_or => try sema.zirBitwise(block, inst, .bit_or),
- .bitcast => try sema.zirBitcast(block, inst),
- .bitcast_result_ptr => try sema.zirBitcastResultPtr(block, inst),
- .block => try sema.zirBlock(block, inst),
- .bool_not => try sema.zirBoolNot(block, inst),
- .bool_and => try sema.zirBoolOp(block, inst, false),
- .bool_or => try sema.zirBoolOp(block, inst, true),
- .bool_br_and => try sema.zirBoolBr(block, inst, false),
- .bool_br_or => try sema.zirBoolBr(block, inst, true),
- .call => try sema.zirCall(block, inst, .auto, false),
- .call_chkused => try sema.zirCall(block, inst, .auto, true),
- .call_compile_time => try sema.zirCall(block, inst, .compile_time, false),
- .call_none => try sema.zirCallNone(block, inst, false),
- .call_none_chkused => try sema.zirCallNone(block, inst, true),
- .cmp_eq => try sema.zirCmp(block, inst, .eq),
- .cmp_gt => try sema.zirCmp(block, inst, .gt),
- .cmp_gte => try sema.zirCmp(block, inst, .gte),
- .cmp_lt => try sema.zirCmp(block, inst, .lt),
- .cmp_lte => try sema.zirCmp(block, inst, .lte),
- .cmp_neq => try sema.zirCmp(block, inst, .neq),
- .coerce_result_ptr => try sema.zirCoerceResultPtr(block, inst),
- .decl_ref => try sema.zirDeclRef(block, inst),
- .decl_val => try sema.zirDeclVal(block, inst),
- .load => try sema.zirLoad(block, inst),
- .elem_ptr => try sema.zirElemPtr(block, inst),
- .elem_ptr_node => try sema.zirElemPtrNode(block, inst),
- .elem_val => try sema.zirElemVal(block, inst),
- .elem_val_node => try sema.zirElemValNode(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),
- .int_to_enum => try sema.zirIntToEnum(block, inst),
- .err_union_code => try sema.zirErrUnionCode(block, inst),
- .err_union_code_ptr => try sema.zirErrUnionCodePtr(block, inst),
- .err_union_payload_safe => try sema.zirErrUnionPayload(block, inst, true),
- .err_union_payload_safe_ptr => try sema.zirErrUnionPayloadPtr(block, inst, true),
- .err_union_payload_unsafe => try sema.zirErrUnionPayload(block, inst, false),
+ // zig fmt: off
+ .alloc => try sema.zirAlloc(block, inst),
+ .alloc_inferred => try sema.zirAllocInferred(block, inst, Type.initTag(.inferred_alloc_const)),
+ .alloc_inferred_mut => try sema.zirAllocInferred(block, inst, Type.initTag(.inferred_alloc_mut)),
+ .alloc_mut => try sema.zirAllocMut(block, inst),
+ .array_cat => try sema.zirArrayCat(block, inst),
+ .array_mul => try sema.zirArrayMul(block, inst),
+ .array_type => try sema.zirArrayType(block, inst),
+ .array_type_sentinel => try sema.zirArrayTypeSentinel(block, inst),
+ .as => try sema.zirAs(block, inst),
+ .as_node => try sema.zirAsNode(block, inst),
+ .@"asm" => try sema.zirAsm(block, inst, false),
+ .asm_volatile => try sema.zirAsm(block, inst, true),
+ .bit_and => try sema.zirBitwise(block, inst, .bit_and),
+ .bit_not => try sema.zirBitNot(block, inst),
+ .bit_or => try sema.zirBitwise(block, inst, .bit_or),
+ .bitcast => try sema.zirBitcast(block, inst),
+ .bitcast_result_ptr => try sema.zirBitcastResultPtr(block, inst),
+ .block => try sema.zirBlock(block, inst),
+ .bool_not => try sema.zirBoolNot(block, inst),
+ .bool_and => try sema.zirBoolOp(block, inst, false),
+ .bool_or => try sema.zirBoolOp(block, inst, true),
+ .bool_br_and => try sema.zirBoolBr(block, inst, false),
+ .bool_br_or => try sema.zirBoolBr(block, inst, true),
+ .c_import => try sema.zirCImport(block, inst),
+ .call => try sema.zirCall(block, inst, .auto, false),
+ .call_chkused => try sema.zirCall(block, inst, .auto, true),
+ .call_compile_time => try sema.zirCall(block, inst, .compile_time, false),
+ .call_none => try sema.zirCallNone(block, inst, false),
+ .call_none_chkused => try sema.zirCallNone(block, inst, true),
+ .cmp_eq => try sema.zirCmp(block, inst, .eq),
+ .cmp_gt => try sema.zirCmp(block, inst, .gt),
+ .cmp_gte => try sema.zirCmp(block, inst, .gte),
+ .cmp_lt => try sema.zirCmp(block, inst, .lt),
+ .cmp_lte => try sema.zirCmp(block, inst, .lte),
+ .cmp_neq => try sema.zirCmp(block, inst, .neq),
+ .coerce_result_ptr => try sema.zirCoerceResultPtr(block, inst),
+ .decl_ref => try sema.zirDeclRef(block, inst),
+ .decl_val => try sema.zirDeclVal(block, inst),
+ .load => try sema.zirLoad(block, inst),
+ .elem_ptr => try sema.zirElemPtr(block, inst),
+ .elem_ptr_node => try sema.zirElemPtrNode(block, inst),
+ .elem_val => try sema.zirElemVal(block, inst),
+ .elem_val_node => try sema.zirElemValNode(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),
+ .int_to_enum => try sema.zirIntToEnum(block, inst),
+ .err_union_code => try sema.zirErrUnionCode(block, inst),
+ .err_union_code_ptr => try sema.zirErrUnionCodePtr(block, inst),
+ .err_union_payload_safe => try sema.zirErrUnionPayload(block, inst, true),
+ .err_union_payload_safe_ptr => try sema.zirErrUnionPayloadPtr(block, inst, true),
+ .err_union_payload_unsafe => try sema.zirErrUnionPayload(block, inst, false),
.err_union_payload_unsafe_ptr => try sema.zirErrUnionPayloadPtr(block, inst, false),
- .error_union_type => try sema.zirErrorUnionType(block, inst),
- .error_value => try sema.zirErrorValue(block, inst),
- .error_to_int => try sema.zirErrorToInt(block, inst),
- .int_to_error => try sema.zirIntToError(block, inst),
- .field_ptr => try sema.zirFieldPtr(block, inst),
- .field_ptr_named => try sema.zirFieldPtrNamed(block, inst),
- .field_val => try sema.zirFieldVal(block, inst),
- .field_val_named => try sema.zirFieldValNamed(block, inst),
- .floatcast => try sema.zirFloatcast(block, inst),
- .func => try sema.zirFunc(block, inst, false),
- .func_extra => try sema.zirFuncExtra(block, inst, false),
- .func_extra_var_args => try sema.zirFuncExtra(block, inst, true),
- .func_var_args => try sema.zirFunc(block, inst, true),
- .has_decl => try sema.zirHasDecl(block, inst),
- .import => try sema.zirImport(block, inst),
- .indexable_ptr_len => try sema.zirIndexablePtrLen(block, inst),
- .int => try sema.zirInt(block, inst),
- .float => try sema.zirFloat(block, inst),
- .float128 => try sema.zirFloat128(block, inst),
- .int_type => try sema.zirIntType(block, inst),
- .intcast => try sema.zirIntcast(block, inst),
- .is_err => try sema.zirIsErr(block, inst),
- .is_err_ptr => try sema.zirIsErrPtr(block, inst),
- .is_non_null => try sema.zirIsNull(block, inst, true),
- .is_non_null_ptr => try sema.zirIsNullPtr(block, inst, true),
- .is_null => try sema.zirIsNull(block, inst, false),
- .is_null_ptr => try sema.zirIsNullPtr(block, inst, false),
- .loop => try sema.zirLoop(block, inst),
- .merge_error_sets => try sema.zirMergeErrorSets(block, inst),
- .negate => try sema.zirNegate(block, inst, .sub),
- .negate_wrap => try sema.zirNegate(block, inst, .subwrap),
- .optional_payload_safe => try sema.zirOptionalPayload(block, inst, true),
- .optional_payload_safe_ptr => try sema.zirOptionalPayloadPtr(block, inst, true),
- .optional_payload_unsafe => try sema.zirOptionalPayload(block, inst, false),
- .optional_payload_unsafe_ptr => try sema.zirOptionalPayloadPtr(block, inst, false),
- .optional_type => try sema.zirOptionalType(block, inst),
- .optional_type_from_ptr_elem => try sema.zirOptionalTypeFromPtrElem(block, inst),
- .param_type => try sema.zirParamType(block, inst),
- .ptr_type => try sema.zirPtrType(block, inst),
- .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),
- .slice_sentinel => try sema.zirSliceSentinel(block, inst),
- .slice_start => try sema.zirSliceStart(block, inst),
- .str => try sema.zirStr(block, inst),
- .switch_block => try sema.zirSwitchBlock(block, inst, false, .none),
- .switch_block_multi => try sema.zirSwitchBlockMulti(block, inst, false, .none),
- .switch_block_else => try sema.zirSwitchBlock(block, inst, false, .@"else"),
- .switch_block_else_multi => try sema.zirSwitchBlockMulti(block, inst, false, .@"else"),
- .switch_block_under => try sema.zirSwitchBlock(block, inst, false, .under),
- .switch_block_under_multi => try sema.zirSwitchBlockMulti(block, inst, false, .under),
- .switch_block_ref => try sema.zirSwitchBlock(block, inst, true, .none),
- .switch_block_ref_multi => try sema.zirSwitchBlockMulti(block, inst, true, .none),
- .switch_block_ref_else => try sema.zirSwitchBlock(block, inst, true, .@"else"),
- .switch_block_ref_else_multi => try sema.zirSwitchBlockMulti(block, inst, true, .@"else"),
- .switch_block_ref_under => try sema.zirSwitchBlock(block, inst, true, .under),
+ .error_union_type => try sema.zirErrorUnionType(block, inst),
+ .error_value => try sema.zirErrorValue(block, inst),
+ .error_to_int => try sema.zirErrorToInt(block, inst),
+ .int_to_error => try sema.zirIntToError(block, inst),
+ .field_ptr => try sema.zirFieldPtr(block, inst),
+ .field_ptr_named => try sema.zirFieldPtrNamed(block, inst),
+ .field_val => try sema.zirFieldVal(block, inst),
+ .field_val_named => try sema.zirFieldValNamed(block, inst),
+ .floatcast => try sema.zirFloatcast(block, inst),
+ .func => try sema.zirFunc(block, inst, false),
+ .func_extra => try sema.zirFuncExtra(block, inst, false),
+ .func_extra_var_args => try sema.zirFuncExtra(block, inst, true),
+ .func_var_args => try sema.zirFunc(block, inst, true),
+ .import => try sema.zirImport(block, inst),
+ .indexable_ptr_len => try sema.zirIndexablePtrLen(block, inst),
+ .int => try sema.zirInt(block, inst),
+ .float => try sema.zirFloat(block, inst),
+ .float128 => try sema.zirFloat128(block, inst),
+ .int_type => try sema.zirIntType(block, inst),
+ .intcast => try sema.zirIntcast(block, inst),
+ .is_err => try sema.zirIsErr(block, inst),
+ .is_err_ptr => try sema.zirIsErrPtr(block, inst),
+ .is_non_null => try sema.zirIsNull(block, inst, true),
+ .is_non_null_ptr => try sema.zirIsNullPtr(block, inst, true),
+ .is_null => try sema.zirIsNull(block, inst, false),
+ .is_null_ptr => try sema.zirIsNullPtr(block, inst, false),
+ .loop => try sema.zirLoop(block, inst),
+ .merge_error_sets => try sema.zirMergeErrorSets(block, inst),
+ .negate => try sema.zirNegate(block, inst, .sub),
+ .negate_wrap => try sema.zirNegate(block, inst, .subwrap),
+ .optional_payload_safe => try sema.zirOptionalPayload(block, inst, true),
+ .optional_payload_safe_ptr => try sema.zirOptionalPayloadPtr(block, inst, true),
+ .optional_payload_unsafe => try sema.zirOptionalPayload(block, inst, false),
+ .optional_payload_unsafe_ptr => try sema.zirOptionalPayloadPtr(block, inst, false),
+ .optional_type => try sema.zirOptionalType(block, inst),
+ .optional_type_from_ptr_elem => try sema.zirOptionalTypeFromPtrElem(block, inst),
+ .param_type => try sema.zirParamType(block, inst),
+ .ptr_type => try sema.zirPtrType(block, inst),
+ .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),
+ .slice_sentinel => try sema.zirSliceSentinel(block, inst),
+ .slice_start => try sema.zirSliceStart(block, inst),
+ .str => try sema.zirStr(block, inst),
+ .switch_block => try sema.zirSwitchBlock(block, inst, false, .none),
+ .switch_block_multi => try sema.zirSwitchBlockMulti(block, inst, false, .none),
+ .switch_block_else => try sema.zirSwitchBlock(block, inst, false, .@"else"),
+ .switch_block_else_multi => try sema.zirSwitchBlockMulti(block, inst, false, .@"else"),
+ .switch_block_under => try sema.zirSwitchBlock(block, inst, false, .under),
+ .switch_block_under_multi => try sema.zirSwitchBlockMulti(block, inst, false, .under),
+ .switch_block_ref => try sema.zirSwitchBlock(block, inst, true, .none),
+ .switch_block_ref_multi => try sema.zirSwitchBlockMulti(block, inst, true, .none),
+ .switch_block_ref_else => try sema.zirSwitchBlock(block, inst, true, .@"else"),
+ .switch_block_ref_else_multi => try sema.zirSwitchBlockMulti(block, inst, true, .@"else"),
+ .switch_block_ref_under => try sema.zirSwitchBlock(block, inst, true, .under),
.switch_block_ref_under_multi => try sema.zirSwitchBlockMulti(block, inst, true, .under),
- .switch_capture => try sema.zirSwitchCapture(block, inst, false, false),
- .switch_capture_ref => try sema.zirSwitchCapture(block, inst, false, true),
- .switch_capture_multi => try sema.zirSwitchCapture(block, inst, true, false),
- .switch_capture_multi_ref => try sema.zirSwitchCapture(block, inst, true, true),
- .switch_capture_else => try sema.zirSwitchCaptureElse(block, inst, false),
- .switch_capture_else_ref => try sema.zirSwitchCaptureElse(block, inst, true),
- .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),
- .fence => try sema.zirFence(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),
- .log2_int_type => try sema.zirLog2IntType(block, inst),
- .xor => try sema.zirBitwise(block, inst, .xor),
- .struct_init_empty => try sema.zirStructInitEmpty(block, inst),
- .struct_init => try sema.zirStructInit(block, inst),
- .field_type => try sema.zirFieldType(block, inst),
-
- .struct_decl => try sema.zirStructDecl(block, inst, .Auto),
- .struct_decl_packed => try sema.zirStructDecl(block, inst, .Packed),
- .struct_decl_extern => try sema.zirStructDecl(block, inst, .Extern),
- .enum_decl => try sema.zirEnumDecl(block, inst, false),
+ .switch_capture => try sema.zirSwitchCapture(block, inst, false, false),
+ .switch_capture_ref => try sema.zirSwitchCapture(block, inst, false, true),
+ .switch_capture_multi => try sema.zirSwitchCapture(block, inst, true, false),
+ .switch_capture_multi_ref => try sema.zirSwitchCapture(block, inst, true, true),
+ .switch_capture_else => try sema.zirSwitchCaptureElse(block, inst, false),
+ .switch_capture_else_ref => try sema.zirSwitchCaptureElse(block, inst, true),
+ .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),
+ .log2_int_type => try sema.zirLog2IntType(block, inst),
+ .typeof_log2_int_type => try sema.zirTypeofLog2IntType(block, inst),
+ .xor => try sema.zirBitwise(block, inst, .xor),
+ .struct_init_empty => try sema.zirStructInitEmpty(block, inst),
+ .struct_init => try sema.zirStructInit(block, inst),
+ .union_init_ptr => try sema.zirUnionInitPtr(block, inst),
+ .field_type => try sema.zirFieldType(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),
+ .embed_file => try sema.zirEmbedFile(block, inst),
+ .error_name => try sema.zirErrorName(block, inst),
+ .tag_name => try sema.zirTagName(block, inst),
+ .reify => try sema.zirReify(block, inst),
+ .type_name => try sema.zirTypeName(block, inst),
+ .frame_type => try sema.zirFrameType(block, inst),
+ .frame_size => try sema.zirFrameSize(block, inst),
+ .float_to_int => try sema.zirFloatToInt(block, inst),
+ .int_to_float => try sema.zirIntToFloat(block, inst),
+ .int_to_ptr => try sema.zirIntToPtr(block, inst),
+ .float_cast => try sema.zirFloatCast(block, inst),
+ .int_cast => try sema.zirIntCast(block, inst),
+ .err_set_cast => try sema.zirErrSetCast(block, inst),
+ .ptr_cast => try sema.zirPtrCast(block, inst),
+ .truncate => try sema.zirTruncate(block, inst),
+ .align_cast => try sema.zirAlignCast(block, inst),
+ .has_decl => try sema.zirHasDecl(block, inst),
+ .has_field => try sema.zirHasField(block, inst),
+ .clz => try sema.zirClz(block, inst),
+ .ctz => try sema.zirCtz(block, inst),
+ .pop_count => try sema.zirPopCount(block, inst),
+ .byte_swap => try sema.zirByteSwap(block, inst),
+ .bit_reverse => try sema.zirBitReverse(block, inst),
+ .div_exact => try sema.zirDivExact(block, inst),
+ .div_floor => try sema.zirDivFloor(block, inst),
+ .div_trunc => try sema.zirDivTrunc(block, inst),
+ .mod => try sema.zirMod(block, inst),
+ .rem => try sema.zirRem(block, inst),
+ .shl_exact => try sema.zirShlExact(block, inst),
+ .shr_exact => try sema.zirShrExact(block, inst),
+ .bit_offset_of => try sema.zirBitOffsetOf(block, inst),
+ .byte_offset_of => try sema.zirByteOffsetOf(block, inst),
+ .cmpxchg_strong => try sema.zirCmpxchg(block, inst),
+ .cmpxchg_weak => try sema.zirCmpxchg(block, inst),
+ .splat => try sema.zirSplat(block, inst),
+ .reduce => try sema.zirReduce(block, inst),
+ .shuffle => try sema.zirShuffle(block, inst),
+ .atomic_load => try sema.zirAtomicLoad(block, inst),
+ .atomic_rmw => try sema.zirAtomicRmw(block, inst),
+ .atomic_store => try sema.zirAtomicStore(block, inst),
+ .mul_add => try sema.zirMulAdd(block, inst),
+ .builtin_call => try sema.zirBuiltinCall(block, inst),
+ .field_ptr_type => try sema.zirFieldPtrType(block, inst),
+ .field_parent_ptr => try sema.zirFieldParentPtr(block, inst),
+ .memcpy => try sema.zirMemcpy(block, inst),
+ .memset => try sema.zirMemset(block, inst),
+ .builtin_async_call => try sema.zirBuiltinAsyncCall(block, inst),
+ .extended => try sema.zirExtended(block, inst),
+
+ .sqrt => try sema.zirUnaryMath(block, inst),
+ .sin => try sema.zirUnaryMath(block, inst),
+ .cos => try sema.zirUnaryMath(block, inst),
+ .exp => try sema.zirUnaryMath(block, inst),
+ .exp2 => try sema.zirUnaryMath(block, inst),
+ .log => try sema.zirUnaryMath(block, inst),
+ .log2 => try sema.zirUnaryMath(block, inst),
+ .log10 => try sema.zirUnaryMath(block, inst),
+ .fabs => try sema.zirUnaryMath(block, inst),
+ .floor => try sema.zirUnaryMath(block, inst),
+ .ceil => try sema.zirUnaryMath(block, inst),
+ .trunc => try sema.zirUnaryMath(block, inst),
+ .round => try sema.zirUnaryMath(block, inst),
+
+ .struct_decl => try sema.zirStructDecl(block, inst, .Auto),
+ .struct_decl_packed => try sema.zirStructDecl(block, inst, .Packed),
+ .struct_decl_extern => try sema.zirStructDecl(block, inst, .Extern),
+ .enum_decl => try sema.zirEnumDecl(block, inst, false),
.enum_decl_nonexhaustive => try sema.zirEnumDecl(block, inst, true),
- .union_decl => try sema.zirUnionDecl(block, inst),
- .opaque_decl => try sema.zirOpaqueDecl(block, inst),
+ .union_decl => try sema.zirUnionDecl(block, inst),
+ .opaque_decl => try sema.zirOpaqueDecl(block, inst),
- .add => try sema.zirArithmetic(block, inst),
+ .add => try sema.zirArithmetic(block, inst),
.addwrap => try sema.zirArithmetic(block, inst),
- .div => try sema.zirArithmetic(block, inst),
+ .div => try sema.zirArithmetic(block, inst),
.mod_rem => try sema.zirArithmetic(block, inst),
- .mul => try sema.zirArithmetic(block, inst),
+ .mul => try sema.zirArithmetic(block, inst),
.mulwrap => try sema.zirArithmetic(block, inst),
- .sub => try sema.zirArithmetic(block, inst),
+ .sub => try sema.zirArithmetic(block, inst),
.subwrap => try sema.zirArithmetic(block, inst),
.add_with_overflow => try sema.zirOverflowArithmetic(block, inst),
@@ -294,15 +362,17 @@ pub fn analyzeBody(
// Instructions that we know to *always* be noreturn based solely on their tag.
// These functions match the return type of analyzeBody so that we can
// tail call them here.
- .condbr => return sema.zirCondbr(block, inst),
- .@"break" => return sema.zirBreak(block, inst),
- .break_inline => return inst,
- .compile_error => return sema.zirCompileError(block, inst),
- .ret_coerce => return sema.zirRetTok(block, inst, true),
- .ret_node => return sema.zirRetNode(block, inst),
- .ret_tok => return sema.zirRetTok(block, inst, false),
+ .break_inline => return inst,
+ .condbr => return sema.zirCondbr(block, inst),
+ .@"break" => return sema.zirBreak(block, inst),
+ .compile_error => return sema.zirCompileError(block, inst),
+ .ret_coerce => return sema.zirRetTok(block, inst, true),
+ .ret_node => return sema.zirRetNode(block, inst),
+ .ret_tok => return sema.zirRetTok(block, inst, false),
.@"unreachable" => return sema.zirUnreachable(block, inst),
- .repeat => return sema.zirRepeat(block, inst),
+ .repeat => return sema.zirRepeat(block, inst),
+ .panic => return sema.zirPanic(block, inst),
+ // zig fmt: on
// Instructions that we know can *never* be noreturn based solely on
// their tag. We avoid needlessly checking if they are noreturn and
@@ -313,6 +383,10 @@ pub fn analyzeBody(
try sema.zirBreakpoint(block, inst);
continue;
},
+ .fence => {
+ try sema.zirFence(block, inst);
+ continue;
+ },
.dbg_stmt_node => {
try sema.zirDbgStmtNode(block, inst);
continue;
@@ -365,6 +439,22 @@ pub fn analyzeBody(
try sema.zirExport(block, inst);
continue;
},
+ .set_align_stack => {
+ try sema.zirSetAlignStack(block, inst);
+ continue;
+ },
+ .set_cold => {
+ try sema.zirSetAlignStack(block, inst);
+ continue;
+ },
+ .set_float_mode => {
+ try sema.zirSetFloatMode(block, inst);
+ continue;
+ },
+ .set_runtime_safety => {
+ try sema.zirSetRuntimeSafety(block, inst);
+ continue;
+ },
// Special case instructions to handle comptime control flow.
.repeat_inline => {
@@ -1382,6 +1472,13 @@ fn zirRepeat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!
return always_noreturn;
}
+fn zirPanic(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Zir.Inst.Index {
+ const inst_data = sema.code.instructions.items(.data)[inst].un_node;
+ const src: LazySrcLoc = inst_data.src();
+ return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirPanic", .{});
+ //return always_noreturn;
+}
+
fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
const tracy = trace(@src());
defer tracy.end();
@@ -1443,6 +1540,16 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) InnerE
return sema.analyzeBlockBody(parent_block, src, &child_block, merges);
}
+fn zirCImport(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
+ const tracy = trace(@src());
+ defer tracy.end();
+
+ const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
+ const src = inst_data.src();
+
+ return sema.mod.fail(&parent_block.base, src, "TODO: implement Sema.zirCImport", .{});
+}
+
fn zirBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
const tracy = trace(@src());
defer tracy.end();
@@ -1597,6 +1704,30 @@ fn zirExport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!
try sema.mod.analyzeExport(&block.base, src, export_name, actual_fn.owner_decl);
}
+fn zirSetAlignStack(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!void {
+ const inst_data = sema.code.instructions.items(.data)[inst].un_node;
+ const src: LazySrcLoc = inst_data.src();
+ return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirSetAlignStack", .{});
+}
+
+fn zirSetCold(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!void {
+ const inst_data = sema.code.instructions.items(.data)[inst].un_node;
+ const src: LazySrcLoc = inst_data.src();
+ return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirSetCold", .{});
+}
+
+fn zirSetFloatMode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!void {
+ const inst_data = sema.code.instructions.items(.data)[inst].un_node;
+ const src: LazySrcLoc = inst_data.src();
+ return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirSetFloatMode", .{});
+}
+
+fn zirSetRuntimeSafety(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!void {
+ const inst_data = sema.code.instructions.items(.data)[inst].un_node;
+ const src: LazySrcLoc = inst_data.src();
+ return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirSetRuntimeSafety", .{});
+}
+
fn zirBreakpoint(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!void {
const tracy = trace(@src());
defer tracy.end();
@@ -1607,6 +1738,12 @@ fn zirBreakpoint(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr
_ = try block.addNoOp(src, Type.initTag(.void), .breakpoint);
}
+fn zirFence(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!void {
+ const src_node = sema.code.instructions.items(.data)[inst].node;
+ const src: LazySrcLoc = .{ .node_offset = src_node };
+ return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirFence", .{});
+}
+
fn zirBreak(sema: *Sema, start_block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Zir.Inst.Index {
const tracy = trace(@src());
defer tracy.end();
@@ -3874,10 +4011,15 @@ fn validateSwitchNoRange(
return sema.mod.failWithOwnedErrorMsg(&block.base, msg);
}
-fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
- const tracy = trace(@src());
- defer tracy.end();
+fn zirHasField(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
+ const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
+ const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
+ const src = inst_data.src();
+
+ return sema.mod.fail(&block.base, src, "TODO implement zirHasField", .{});
+}
+fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const src = inst_data.src();
@@ -4382,16 +4524,13 @@ fn zirThis(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*I
const src: LazySrcLoc = .{ .node_offset = src_node };
return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirThis", .{});
}
-fn zirFence(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 };
- return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirFence", .{});
-}
+
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 };
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 };
@@ -4419,6 +4558,12 @@ fn zirTypeofElem(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr
return sema.mod.constType(sema.arena, src, elem_ty);
}
+fn zirTypeofLog2IntType(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();
+ return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirTypeofLog2IntType", .{});
+}
+
fn zirLog2IntType(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();
@@ -4827,6 +4972,12 @@ fn zirStructInitEmpty(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) In
});
}
+fn zirUnionInitPtr(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirUnionInitPtr", .{});
+}
+
fn zirStructInit(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();
@@ -4839,6 +4990,380 @@ 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();
+ 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();
+ 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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirFrameAddress", .{});
+}
+
+fn zirPtrToInt(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirPtrToInt", .{});
+}
+
+fn zirAlignOf(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirAlignOf", .{});
+}
+
+fn zirBoolToInt(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirBoolToInt", .{});
+}
+
+fn zirEmbedFile(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirEmbedFile", .{});
+}
+
+fn zirErrorName(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirErrorName", .{});
+}
+
+fn zirUnaryMath(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirUnaryMath", .{});
+}
+
+fn zirTagName(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirTagName", .{});
+}
+
+fn zirReify(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirReify", .{});
+}
+
+fn zirTypeName(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirTypeName", .{});
+}
+
+fn zirFrameType(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirFrameType", .{});
+}
+
+fn zirFrameSize(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirFrameSize", .{});
+}
+
+fn zirFloatToInt(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirFloatToInt", .{});
+}
+
+fn zirIntToFloat(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirIntToFloat", .{});
+}
+
+fn zirIntToPtr(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirIntToPtr", .{});
+}
+
+fn zirFloatCast(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirFloatCast", .{});
+}
+
+fn zirIntCast(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirIntCast", .{});
+}
+
+fn zirErrSetCast(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirErrSetCast", .{});
+}
+
+fn zirPtrCast(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirPtrCast", .{});
+}
+
+fn zirTruncate(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirTruncate", .{});
+}
+
+fn zirAlignCast(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirAlignCast", .{});
+}
+
+fn zirClz(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirClz", .{});
+}
+
+fn zirCtz(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirCtz", .{});
+}
+
+fn zirPopCount(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirPopCount", .{});
+}
+
+fn zirByteSwap(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirByteSwap", .{});
+}
+
+fn zirBitReverse(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirBitReverse", .{});
+}
+
+fn zirDivExact(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirDivExact", .{});
+}
+
+fn zirDivFloor(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirDivFloor", .{});
+}
+
+fn zirDivTrunc(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirDivTrunc", .{});
+}
+
+fn zirMod(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirMod", .{});
+}
+
+fn zirRem(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirRem", .{});
+}
+
+fn zirShlExact(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirShlExact", .{});
+}
+
+fn zirShrExact(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirShrExact", .{});
+}
+
+fn zirBitOffsetOf(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirBitOffsetOf", .{});
+}
+
+fn zirByteOffsetOf(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirByteOffsetOf", .{});
+}
+
+fn zirCmpxchg(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirCmpxchg", .{});
+}
+
+fn zirSplat(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirSplat", .{});
+}
+
+fn zirReduce(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirReduce", .{});
+}
+
+fn zirShuffle(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirShuffle", .{});
+}
+
+fn zirAtomicLoad(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirAtomicLoad", .{});
+}
+
+fn zirAtomicRmw(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirAtomicRmw", .{});
+}
+
+fn zirAtomicStore(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirAtomicStore", .{});
+}
+
+fn zirMulAdd(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirMulAdd", .{});
+}
+
+fn zirBuiltinCall(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirBuiltinCall", .{});
+}
+
+fn zirFieldPtrType(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirFieldPtrType", .{});
+}
+
+fn zirFieldParentPtr(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirFieldParentPtr", .{});
+}
+
+fn zirMemcpy(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirMemcpy", .{});
+}
+
+fn zirMemset(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();
+ return sema.mod.fail(&block.base, src, "TODO: Sema.zirMemset", .{});
+}
+
+fn zirBuiltinAsyncCall(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();
+ 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
+ .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 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;
+ const src: LazySrcLoc = .{ .node_offset = extra.node };
+ return sema.mod.fail(&block.base, src, "TODO: implement Sema.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;
+ const src: LazySrcLoc = .{ .node_offset = extra.node };
+ return sema.mod.fail(&block.base, src, "TODO: implement Sema.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;
+ const src: LazySrcLoc = .{ .node_offset = extra.node };
+ return sema.mod.fail(&block.base, src, "TODO: implement Sema.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;
+ const src: LazySrcLoc = .{ .node_offset = extra.node };
+ return sema.mod.fail(&block.base, src, "TODO: implement Sema.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;
+ const src: LazySrcLoc = .{ .node_offset = extra.node };
+ return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirWasmMemoryGrow", .{});
+}
+
fn requireFunctionBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void {
if (sema.func == null) {
return sema.mod.fail(&block.base, src, "instruction illegal outside function body", .{});
diff --git a/src/Zir.zig b/src/Zir.zig
index 879f8d2459..4348b36fa4 100644
--- a/src/Zir.zig
+++ b/src/Zir.zig
@@ -274,9 +274,6 @@ pub const Inst = struct {
/// Uses the `bin` union field.
/// LHS is destination element type, RHS is result pointer.
coerce_result_ptr,
- /// Emit an error message and fail compilation.
- /// Uses the `un_node` field.
- compile_error,
/// Log compile time variables and emit an error message.
/// Uses the `pl_node` union field. The AST node is the compile log builtin call.
/// The payload is `MultiOp`.
@@ -339,9 +336,6 @@ pub const Inst = struct {
/// Same as `elem_val` except also stores a source location node.
/// Uses the `pl_node` union field. AST node is a[b] syntax. Payload is `Bin`.
elem_val_node,
- /// This instruction has been deleted late in the astgen phase. It must
- /// be ignored, and the corresponding `Data` is undefined.
- elided,
/// Emits a compile error if the operand is not `void`.
/// Uses the `un_node` field.
ensure_result_used,
@@ -391,9 +385,6 @@ pub const Inst = struct {
func_extra,
/// Same as `func_extra` but the function is variadic.
func_extra_var_args,
- /// Implements the `@hasDecl` builtin.
- /// Uses the `pl_node` union field. Payload is `Bin`.
- has_decl,
/// Implements the `@import` builtin.
/// Uses the `str_tok` field.
import,
@@ -412,10 +403,6 @@ pub const Inst = struct {
/// Make an integer type out of signedness and bit count.
/// Payload is `int_type`
int_type,
- /// Convert an error type to `u16`
- error_to_int,
- /// Convert a `u16` to `anyerror`
- int_to_error,
/// Return a boolean false if an optional is null. `x != null`
/// Uses the `un_node` field.
is_non_null,
@@ -498,16 +485,6 @@ pub const Inst = struct {
/// Same as `ret_tok` except the operand needs to get coerced to the function's
/// return type.
ret_coerce,
- /// Changes the maximum number of backwards branches that compile-time
- /// code execution can use before giving up and making a compile error.
- /// Uses the `un_node` union field.
- set_eval_branch_quota,
- /// Integer shift-left. Zeroes are shifted in from the right hand side.
- /// Uses the `pl_node` union field. Payload is `Bin`.
- shl,
- /// Integer shift-right. Arithmetic or logical depending on the signedness of the integer type.
- /// Uses the `pl_node` union field. Payload is `Bin`.
- shr,
/// Create a pointer type that does not have a sentinel, alignment, or bit range specified.
/// Uses the `ptr_type_simple` union field.
ptr_type_simple,
@@ -573,6 +550,10 @@ pub const Inst = struct {
/// of one or more params.
/// Uses the `pl_node` field. AST node is the `@TypeOf` call. Payload is `MultiOp`.
typeof_peer,
+ /// Given a value, look at the type of it, which must be an integer type.
+ /// Returns the integer type for the RHS of a shift operation.
+ /// Uses the `un_node` field.
+ typeof_log2_int_type,
/// Given an integer type, returns the integer type for the RHS of a shift operation.
/// Uses the `un_node` field.
log2_int_type,
@@ -712,12 +693,10 @@ pub const Inst = struct {
/// struct value.
/// Uses the `pl_node` field. Payload is `StructInit`.
struct_init,
- /// Converts an integer into an enum value.
- /// Uses `pl_node` with payload `Bin`. `lhs` is enum type, `rhs` is operand.
- int_to_enum,
- /// Converts an enum value into an integer. Resulting type will be the tag type
- /// of the enum. Uses `un_node`.
- enum_to_int,
+ /// 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`.
+ union_init_ptr,
/// Implements the `@typeInfo` builtin. Uses `un_node`.
type_info,
/// Implements the `@sizeOf` builtin. Uses `un_node`.
@@ -741,6 +720,224 @@ 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`.
+ error_to_int,
+ /// Implement builtin `@intToError`. Uses `un_node`.
+ int_to_error,
+ /// Emit an error message and fail compilation.
+ /// Uses the `un_node` field.
+ compile_error,
+ /// Changes the maximum number of backwards branches that compile-time
+ /// code execution can use before giving up and making a compile error.
+ /// Uses the `un_node` union field.
+ set_eval_branch_quota,
+ /// Converts an enum value into an integer. Resulting type will be the tag type
+ /// of the enum. Uses `un_node`.
+ enum_to_int,
+ /// Implement builtin `@alignOf`. Uses `un_node`.
+ align_of,
+ /// Implement builtin `@boolToInt`. Uses `un_node`.
+ bool_to_int,
+ /// Implement builtin `@embedFile`. Uses `un_node`.
+ embed_file,
+ /// Implement builtin `@errorName`. Uses `un_node`.
+ error_name,
+ /// Implement builtin `@panic`. Uses `un_node`.
+ panic,
+ /// Implement builtin `@setAlignStack`. Uses `un_node`.
+ set_align_stack,
+ /// Implement builtin `@setCold`. Uses `un_node`.
+ set_cold,
+ /// Implement builtin `@setFloatMode`. Uses `un_node`.
+ set_float_mode,
+ /// Implement builtin `@setRuntimeSafety`. Uses `un_node`.
+ set_runtime_safety,
+ /// Implement builtin `@sqrt`. Uses `un_node`.
+ sqrt,
+ /// Implement builtin `@sin`. Uses `un_node`.
+ sin,
+ /// Implement builtin `@cos`. Uses `un_node`.
+ cos,
+ /// Implement builtin `@exp`. Uses `un_node`.
+ exp,
+ /// Implement builtin `@exp2`. Uses `un_node`.
+ exp2,
+ /// Implement builtin `@log`. Uses `un_node`.
+ log,
+ /// Implement builtin `@log2`. Uses `un_node`.
+ log2,
+ /// Implement builtin `@log10`. Uses `un_node`.
+ log10,
+ /// Implement builtin `@fabs`. Uses `un_node`.
+ fabs,
+ /// Implement builtin `@floor`. Uses `un_node`.
+ floor,
+ /// Implement builtin `@ceil`. Uses `un_node`.
+ ceil,
+ /// Implement builtin `@trunc`. Uses `un_node`.
+ trunc,
+ /// Implement builtin `@round`. Uses `un_node`.
+ round,
+ /// Implement builtin `@tagName`. Uses `un_node`.
+ tag_name,
+ /// Implement builtin `@Type`. Uses `un_node`.
+ reify,
+ /// Implement builtin `@typeName`. Uses `un_node`.
+ type_name,
+ /// Implement builtin `@Frame`. Uses `un_node`.
+ frame_type,
+ /// Implement builtin `@frameSize`. Uses `un_node`.
+ frame_size,
+
+ /// Implements the `@floatToInt` builtin.
+ /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
+ float_to_int,
+ /// Implements the `@intToFloat` builtin.
+ /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
+ int_to_float,
+ /// Implements the `@intToPtr` builtin.
+ /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
+ int_to_ptr,
+ /// Converts an integer into an enum value.
+ /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
+ int_to_enum,
+ /// Implements the `@floatCast` builtin.
+ /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
+ float_cast,
+ /// Implements the `@intCast` builtin.
+ /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
+ int_cast,
+ /// Implements the `@errSetCast` builtin.
+ /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
+ err_set_cast,
+ /// Implements the `@ptrCast` builtin.
+ /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
+ ptr_cast,
+ /// Implements the `@truncate` builtin.
+ /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
+ truncate,
+ /// Implements the `@alignCast` builtin.
+ /// Uses `pl_node` with payload `Bin`. `lhs` is dest alignment, `rhs` is operand.
+ align_cast,
+
+ /// Implements the `@hasDecl` builtin.
+ /// Uses the `pl_node` union field. Payload is `Bin`.
+ has_decl,
+ /// Implements the `@hasField` builtin.
+ /// Uses the `pl_node` union field. Payload is `Bin`.
+ has_field,
+
+ /// Implements the `@clz` builtin. Uses the `un_node` union field.
+ clz,
+ /// Implements the `@ctz` builtin. Uses the `un_node` union field.
+ ctz,
+ /// Implements the `@popCount` builtin. Uses the `un_node` union field.
+ pop_count,
+ /// Implements the `@byteSwap` builtin. Uses the `un_node` union field.
+ byte_swap,
+ /// Implements the `@bitReverse` builtin. Uses the `un_node` union field.
+ bit_reverse,
+
+ /// Implements the `@divExact` builtin.
+ /// Uses the `pl_node` union field with payload `Bin`.
+ div_exact,
+ /// Implements the `@divFloor` builtin.
+ /// Uses the `pl_node` union field with payload `Bin`.
+ div_floor,
+ /// Implements the `@divTrunc` builtin.
+ /// Uses the `pl_node` union field with payload `Bin`.
+ div_trunc,
+ /// Implements the `@mod` builtin.
+ /// Uses the `pl_node` union field with payload `Bin`.
+ mod,
+ /// Implements the `@rem` builtin.
+ /// Uses the `pl_node` union field with payload `Bin`.
+ rem,
+
+ /// Integer shift-left. Zeroes are shifted in from the right hand side.
+ /// Uses the `pl_node` union field. Payload is `Bin`.
+ shl,
+ /// Implements the `@shlExact` builtin.
+ /// Uses the `pl_node` union field with payload `Bin`.
+ shl_exact,
+ /// Integer shift-right. Arithmetic or logical depending on the signedness of the integer type.
+ /// Uses the `pl_node` union field. Payload is `Bin`.
+ shr,
+ /// Implements the `@shrExact` builtin.
+ /// Uses the `pl_node` union field with payload `Bin`.
+ shr_exact,
+
+ /// Implements the `@bitOffsetOf` builtin.
+ /// Uses the `pl_node` union field with payload `Bin`.
+ bit_offset_of,
+ /// Implements the `@byteOffsetOf` builtin.
+ /// Uses the `pl_node` union field with payload `Bin`.
+ byte_offset_of,
+ /// Implements the `@cmpxchgStrong` builtin.
+ /// Uses the `pl_node` union field with payload `Cmpxchg`.
+ cmpxchg_strong,
+ /// Implements the `@cmpxchgWeak` builtin.
+ /// Uses the `pl_node` union field with payload `Cmpxchg`.
+ cmpxchg_weak,
+ /// Implements the `@splat` builtin.
+ /// Uses the `pl_node` union field with payload `Bin`.
+ splat,
+ /// Implements the `@reduce` builtin.
+ /// Uses the `pl_node` union field with payload `Bin`.
+ reduce,
+ /// Implements the `@shuffle` builtin.
+ /// Uses the `pl_node` union field with payload `Shuffle`.
+ shuffle,
+ /// Implements the `@atomicLoad` builtin.
+ /// Uses the `pl_node` union field with payload `Bin`.
+ atomic_load,
+ /// Implements the `@atomicRmw` builtin.
+ /// Uses the `pl_node` union field with payload `AtomicRmw`.
+ atomic_rmw,
+ /// Implements the `@atomicStore` builtin.
+ /// Uses the `pl_node` union field with payload `AtomicStore`.
+ atomic_store,
+ /// Implements the `@mulAdd` builtin.
+ /// Uses the `pl_node` union field with payload `MulAdd`.
+ mul_add,
+ /// Implements the `@call` builtin.
+ /// Uses the `pl_node` union field with payload `BuiltinCall`.
+ builtin_call,
+ /// Given a type and a field name, returns a pointer to the field type.
+ /// Assumed to be part of a `@fieldParentPtr` builtin call.
+ /// Uses the `bin` union field. LHS is type, RHS is field name.
+ field_ptr_type,
+ /// Implements the `@fieldParentPtr` builtin.
+ /// Uses the `pl_node` union field with payload `FieldParentPtr`.
+ field_parent_ptr,
+ /// Implements the `@memcpy` builtin.
+ /// Uses the `pl_node` union field with payload `Memcpy`.
+ memcpy,
+ /// Implements the `@memset` builtin.
+ /// Uses the `pl_node` union field with payload `Memset`.
+ memset,
+ /// Implements the `@asyncCall` builtin.
+ /// Uses the `pl_node` union field with payload `AsyncCall`.
+ builtin_async_call,
+ /// Implements the `@cImport` builtin.
+ /// Uses the `pl_node` union field with payload `Block`.
+ c_import,
+ /// The ZIR instruction tag is one of the `Extended` ones.
+ /// Uses the `extended` union field.
+ extended,
+
/// Returns whether the instruction is one of the control flow "noreturn" types.
/// Function calls do not count.
pub fn isNoReturn(tag: Tag) bool {
@@ -876,11 +1073,11 @@ pub const Inst = struct {
.slice_sentinel,
.import,
.typeof_peer,
+ .typeof_log2_int_type,
.log2_int_type,
.resolve_inferred_alloc,
.set_eval_branch_quota,
.compile_log,
- .elided,
.switch_capture,
.switch_capture_ref,
.switch_capture_multi,
@@ -902,6 +1099,7 @@ pub const Inst = struct {
.validate_struct_init_ptr,
.struct_init_empty,
.struct_init,
+ .union_init_ptr,
.field_type,
.int_to_enum,
.enum_to_int,
@@ -916,6 +1114,77 @@ pub const Inst = struct {
.sub_with_overflow,
.mul_with_overflow,
.shl_with_overflow,
+ .error_return_trace,
+ .frame,
+ .frame_address,
+ .ptr_to_int,
+ .align_of,
+ .bool_to_int,
+ .embed_file,
+ .error_name,
+ .set_align_stack,
+ .set_cold,
+ .set_float_mode,
+ .set_runtime_safety,
+ .sqrt,
+ .sin,
+ .cos,
+ .exp,
+ .exp2,
+ .log,
+ .log2,
+ .log10,
+ .fabs,
+ .floor,
+ .ceil,
+ .trunc,
+ .round,
+ .tag_name,
+ .reify,
+ .type_name,
+ .frame_type,
+ .frame_size,
+ .float_to_int,
+ .int_to_float,
+ .int_to_ptr,
+ .float_cast,
+ .int_cast,
+ .err_set_cast,
+ .ptr_cast,
+ .truncate,
+ .align_cast,
+ .has_field,
+ .clz,
+ .ctz,
+ .pop_count,
+ .byte_swap,
+ .bit_reverse,
+ .div_exact,
+ .div_floor,
+ .div_trunc,
+ .mod,
+ .rem,
+ .shl_exact,
+ .shr_exact,
+ .bit_offset_of,
+ .byte_offset_of,
+ .cmpxchg_strong,
+ .cmpxchg_weak,
+ .splat,
+ .reduce,
+ .shuffle,
+ .atomic_load,
+ .atomic_rmw,
+ .atomic_store,
+ .mul_add,
+ .builtin_call,
+ .field_ptr_type,
+ .field_parent_ptr,
+ .memcpy,
+ .memset,
+ .builtin_async_call,
+ .c_import,
+ .extended,
=> false,
.@"break",
@@ -929,11 +1198,33 @@ pub const Inst = struct {
.@"unreachable",
.repeat,
.repeat_inline,
+ .panic,
=> true,
};
}
};
+ /// Rarer instructions are here; ones that do not fit in the 8-bit `Tag` enum.
+ /// `noreturn` instructions may not go here; they must be part of the main `Tag` enum.
+ pub const Extended = enum(u16) {
+ /// `operand` is payload index to `UnNode`.
+ c_undef,
+ /// `operand` is payload index to `UnNode`.
+ c_include,
+ /// `operand` is payload index to `BinNode`.
+ c_define,
+ /// `operand` is payload index to `UnNode`.
+ wasm_memory_size,
+ /// `operand` is payload index to `BinNode`.
+ wasm_memory_grow,
+
+ pub const InstData = struct {
+ opcode: Extended,
+ small: u16,
+ operand: u32,
+ };
+ };
+
/// The position of a ZIR instruction within the `Zir` instructions array.
pub const Index = u32;
@@ -1002,6 +1293,14 @@ pub const Inst = struct {
single_const_pointer_to_comptime_int_type,
const_slice_u8_type,
enum_literal_type,
+ manyptr_u8_type,
+ manyptr_const_u8_type,
+ atomic_ordering_type,
+ atomic_rmw_op_type,
+ calling_convention_type,
+ float_mode_type,
+ reduce_op_type,
+ call_options_type,
/// `undefined` (untyped)
undef,
@@ -1025,6 +1324,8 @@ pub const Inst = struct {
zero_usize,
/// `1` (usize)
one_usize,
+ /// `std.builtin.CallingConvention.C`
+ calling_convention_c,
_,
@@ -1191,6 +1492,38 @@ pub const Inst = struct {
.ty = Type.initTag(.type),
.val = Value.initTag(.enum_literal_type),
},
+ .manyptr_u8_type = .{
+ .ty = Type.initTag(.type),
+ .val = Value.initTag(.manyptr_u8_type),
+ },
+ .manyptr_const_u8_type = .{
+ .ty = Type.initTag(.type),
+ .val = Value.initTag(.manyptr_const_u8_type),
+ },
+ .atomic_ordering_type = .{
+ .ty = Type.initTag(.type),
+ .val = Value.initTag(.atomic_ordering_type),
+ },
+ .atomic_rmw_op_type = .{
+ .ty = Type.initTag(.type),
+ .val = Value.initTag(.atomic_rmw_op_type),
+ },
+ .calling_convention_type = .{
+ .ty = Type.initTag(.type),
+ .val = Value.initTag(.calling_convention_type),
+ },
+ .float_mode_type = .{
+ .ty = Type.initTag(.type),
+ .val = Value.initTag(.float_mode_type),
+ },
+ .reduce_op_type = .{
+ .ty = Type.initTag(.type),
+ .val = Value.initTag(.reduce_op_type),
+ },
+ .call_options_type = .{
+ .ty = Type.initTag(.type),
+ .val = Value.initTag(.call_options_type),
+ },
.undef = .{
.ty = Type.initTag(.@"undefined"),
@@ -1236,13 +1569,27 @@ pub const Inst = struct {
.ty = Type.initTag(.empty_struct_literal),
.val = Value.initTag(.empty_struct_value),
},
+ .calling_convention_c = .{
+ .ty = Type.initTag(.calling_convention),
+ .val = .{ .ptr_otherwise = &calling_convention_c_payload.base },
+ },
});
};
+ /// We would like this to be const but `Value` wants a mutable pointer for
+ /// its payload field. Nothing should mutate this though.
+ var calling_convention_c_payload: Value.Payload.U32 = .{
+ .base = .{ .tag = .enum_field_index },
+ .data = @enumToInt(std.builtin.CallingConvention.C),
+ };
+
/// All instructions have an 8-byte payload, which is contained within
/// this union. `Tag` determines which union field is active, as well as
/// how to interpret the data within.
pub const Data = union {
+ /// Used for `Tag.extended`. The extended opcode determines the meaning
+ /// of the `small` and `operand` fields.
+ extended: Extended.InstData,
/// Used for unary operators, with an AST node source location.
un_node: struct {
/// Offset from Decl AST node index.
@@ -1462,6 +1809,12 @@ pub const Inst = struct {
args_len: u32,
};
+ pub const BuiltinCall = struct {
+ options: Ref,
+ callee: Ref,
+ args: Ref,
+ };
+
/// This data is stored inside extra, with two sets of trailing `Ref`:
/// * 0. the then body, according to `then_body_len`.
/// * 1. the else body, according to `else_body_len`.
@@ -1510,6 +1863,17 @@ pub const Inst = struct {
rhs: Ref,
};
+ pub const BinNode = struct {
+ node: i32,
+ lhs: Ref,
+ rhs: Ref,
+ };
+
+ pub const UnNode = struct {
+ node: i32,
+ operand: Ref,
+ };
+
/// This form is supported when there are no ranges, and exactly 1 item per block.
/// Depending on zir tag and len fields, extra fields trail
/// this one in the extra array.
@@ -1679,6 +2043,70 @@ pub const Inst = struct {
ptr: Ref,
};
+ pub const Cmpxchg = struct {
+ ptr: Ref,
+ expected_value: Ref,
+ new_value: Ref,
+ success_order: Ref,
+ fail_order: Ref,
+ };
+
+ pub const AtomicRmw = struct {
+ ptr: Ref,
+ operation: Ref,
+ operand: Ref,
+ ordering: Ref,
+ };
+
+ pub const UnionInitPtr = struct {
+ union_type: Ref,
+ field_name: Ref,
+ };
+
+ pub const AtomicStore = struct {
+ ptr: Ref,
+ operand: Ref,
+ ordering: Ref,
+ };
+
+ pub const MulAdd = struct {
+ mulend1: Ref,
+ mulend2: Ref,
+ addend: Ref,
+ };
+
+ pub const FieldParentPtr = struct {
+ parent_type: Ref,
+ field_name: Ref,
+ field_ptr: Ref,
+ };
+
+ pub const Memcpy = struct {
+ dest: Ref,
+ source: Ref,
+ byte_count: Ref,
+ };
+
+ pub const Memset = struct {
+ dest: Ref,
+ byte: Ref,
+ byte_count: Ref,
+ };
+
+ pub const Shuffle = struct {
+ elem_type: Ref,
+ a: Ref,
+ b: Ref,
+ mask: Ref,
+ };
+
+ pub const AsyncCall = struct {
+ frame_buffer: Ref,
+ result_ptr: Ref,
+ fn_ptr: Ref,
+ args: Ref,
+ };
+
/// Trailing: `CompileErrors.Item` for each `items_len`.
pub const CompileErrors = struct {
items_len: u32,
@@ -1749,13 +2177,11 @@ const Writer = struct {
.negate_wrap,
.call_none,
.call_none_chkused,
- .compile_error,
.load,
.ensure_result_used,
.ensure_result_non_error,
.ptrtoint,
.ret_node,
- .set_eval_branch_quota,
.resolve_inferred_alloc,
.optional_type,
.optional_type_from_ptr_elem,
@@ -1769,8 +2195,6 @@ const Writer = struct {
.err_union_payload_unsafe_ptr,
.err_union_code,
.err_union_code_ptr,
- .int_to_error,
- .error_to_int,
.is_non_null,
.is_null,
.is_non_null_ptr,
@@ -1780,11 +2204,49 @@ const Writer = struct {
.typeof,
.typeof_elem,
.struct_init_empty,
- .enum_to_int,
.type_info,
.size_of,
.bit_size_of,
+ .typeof_log2_int_type,
.log2_int_type,
+ .ptr_to_int,
+ .error_to_int,
+ .int_to_error,
+ .compile_error,
+ .set_eval_branch_quota,
+ .enum_to_int,
+ .align_of,
+ .bool_to_int,
+ .embed_file,
+ .error_name,
+ .panic,
+ .set_align_stack,
+ .set_cold,
+ .set_float_mode,
+ .set_runtime_safety,
+ .sqrt,
+ .sin,
+ .cos,
+ .exp,
+ .exp2,
+ .log,
+ .log2,
+ .log10,
+ .fabs,
+ .floor,
+ .ceil,
+ .trunc,
+ .round,
+ .tag_name,
+ .reify,
+ .type_name,
+ .frame_type,
+ .frame_size,
+ .clz,
+ .ctz,
+ .pop_count,
+ .byte_swap,
+ .bit_reverse,
=> try self.writeUnNode(stream, inst),
.ref,
@@ -1805,7 +2267,6 @@ const Writer = struct {
.float => try self.writeFloat(stream, inst),
.float128 => try self.writeFloat128(stream, inst),
.str => try self.writeStr(stream, inst),
- .elided => try stream.writeAll(")"),
.int_type => try self.writeIntType(stream, inst),
.@"break",
@@ -1824,7 +2285,20 @@ const Writer = struct {
.slice_sentinel,
.union_decl,
.struct_init,
+ .union_init_ptr,
.field_type,
+ .cmpxchg_strong,
+ .cmpxchg_weak,
+ .shuffle,
+ .atomic_rmw,
+ .atomic_store,
+ .mul_add,
+ .builtin_call,
+ .field_ptr_type,
+ .field_parent_ptr,
+ .memcpy,
+ .memset,
+ .builtin_async_call,
=> try self.writePlNode(stream, inst),
.add_with_overflow,
@@ -1851,9 +2325,12 @@ const Writer = struct {
.cmp_neq,
.div,
.has_decl,
+ .has_field,
.mod_rem,
.shl,
+ .shl_exact,
.shr,
+ .shr_exact,
.xor,
.store_node,
.error_union_type,
@@ -1861,7 +2338,26 @@ const Writer = struct {
.merge_error_sets,
.bit_and,
.bit_or,
+ .float_to_int,
+ .int_to_float,
+ .int_to_ptr,
.int_to_enum,
+ .float_cast,
+ .int_cast,
+ .err_set_cast,
+ .ptr_cast,
+ .truncate,
+ .align_cast,
+ .div_exact,
+ .div_floor,
+ .div_trunc,
+ .mod,
+ .rem,
+ .bit_offset_of,
+ .byte_offset_of,
+ .splat,
+ .reduce,
+ .atomic_load,
=> try self.writePlNodeBin(stream, inst),
.call,
@@ -1874,6 +2370,7 @@ const Writer = struct {
.block_inline_var,
.loop,
.validate_struct_init_ptr,
+ .c_import,
=> try self.writePlNodeBlock(stream, inst),
.condbr,
@@ -1926,6 +2423,9 @@ const Writer = struct {
.fence,
.ret_addr,
.builtin_src,
+ .error_return_trace,
+ .frame,
+ .frame_address,
=> try self.writeNode(stream, inst),
.error_value,
@@ -1954,6 +2454,7 @@ const Writer = struct {
.bitcast,
.bitcast_result_ptr,
+ .extended,
=> try stream.writeAll("TODO)"),
}
}
diff --git a/src/type.zig b/src/type.zig
index 0429fd876a..63c1616506 100644
--- a/src/type.zig
+++ b/src/type.zig
@@ -83,6 +83,8 @@ pub const Type = extern union {
.pointer,
.inferred_alloc_const,
.inferred_alloc_mut,
+ .manyptr_u8,
+ .manyptr_const_u8,
=> return .Pointer,
.optional,
@@ -96,11 +98,17 @@ pub const Type = extern union {
.empty_struct,
.empty_struct_literal,
.@"struct",
+ .call_options,
=> return .Struct,
.enum_full,
.enum_nonexhaustive,
.enum_simple,
+ .atomic_ordering,
+ .atomic_rmw_op,
+ .calling_convention,
+ .float_mode,
+ .reduce_op,
=> return .Enum,
.var_args_param => unreachable, // can be any type
@@ -205,6 +213,8 @@ pub const Type = extern union {
.mut_slice,
.optional_single_const_pointer,
.optional_single_mut_pointer,
+ .manyptr_u8,
+ .manyptr_const_u8,
=> self.cast(Payload.ElemType),
.inferred_alloc_const => unreachable,
@@ -271,6 +281,17 @@ pub const Type = extern union {
.@"volatile" = false,
.size = .Many,
} },
+ .manyptr_const_u8 => return .{ .data = .{
+ .pointee_type = Type.initTag(.u8),
+ .sentinel = null,
+ .@"align" = 0,
+ .bit_offset = 0,
+ .host_size = 0,
+ .@"allowzero" = false,
+ .mutable = false,
+ .@"volatile" = false,
+ .size = .Many,
+ } },
.many_mut_pointer => return .{ .data = .{
.pointee_type = self.castPointer().?.data,
.sentinel = null,
@@ -282,6 +303,17 @@ pub const Type = extern union {
.@"volatile" = false,
.size = .Many,
} },
+ .manyptr_u8 => return .{ .data = .{
+ .pointee_type = Type.initTag(.u8),
+ .sentinel = null,
+ .@"align" = 0,
+ .bit_offset = 0,
+ .host_size = 0,
+ .@"allowzero" = false,
+ .mutable = true,
+ .@"volatile" = false,
+ .size = .Many,
+ } },
.c_const_pointer => return .{ .data = .{
.pointee_type = self.castPointer().?.data,
.sentinel = null,
@@ -576,6 +608,14 @@ pub const Type = extern union {
.inferred_alloc_mut,
.var_args_param,
.empty_struct_literal,
+ .manyptr_u8,
+ .manyptr_const_u8,
+ .atomic_ordering,
+ .atomic_rmw_op,
+ .calling_convention,
+ .float_mode,
+ .reduce_op,
+ .call_options,
=> unreachable,
.array_u8,
@@ -746,6 +786,14 @@ pub const Type = extern union {
.fn_naked_noreturn_no_args => return writer.writeAll("fn() callconv(.Naked) noreturn"),
.fn_ccc_void_no_args => return writer.writeAll("fn() callconv(.C) void"),
.single_const_pointer_to_comptime_int => return writer.writeAll("*const comptime_int"),
+ .manyptr_u8 => return writer.writeAll("[*]u8"),
+ .manyptr_const_u8 => return writer.writeAll("[*]const u8"),
+ .atomic_ordering => return writer.writeAll("std.builtin.AtomicOrdering"),
+ .atomic_rmw_op => return writer.writeAll("std.builtin.AtomicRmwOp"),
+ .calling_convention => return writer.writeAll("std.builtin.CallingConvention"),
+ .float_mode => return writer.writeAll("std.builtin.FloatMode"),
+ .reduce_op => return writer.writeAll("std.builtin.ReduceOp"),
+ .call_options => return writer.writeAll("std.builtin.CallOptions"),
.function => {
const payload = ty.castTag(.function).?.data;
try writer.writeAll("fn(");
@@ -952,6 +1000,14 @@ pub const Type = extern union {
.single_const_pointer_to_comptime_int => return Value.initTag(.single_const_pointer_to_comptime_int_type),
.const_slice_u8 => return Value.initTag(.const_slice_u8_type),
.enum_literal => return Value.initTag(.enum_literal_type),
+ .manyptr_u8 => return Value.initTag(.manyptr_u8_type),
+ .manyptr_const_u8 => return Value.initTag(.manyptr_const_u8_type),
+ .atomic_ordering => return Value.initTag(.atomic_ordering_type),
+ .atomic_rmw_op => return Value.initTag(.atomic_rmw_op_type),
+ .calling_convention => return Value.initTag(.calling_convention_type),
+ .float_mode => return Value.initTag(.float_mode_type),
+ .reduce_op => return Value.initTag(.reduce_op_type),
+ .call_options => return Value.initTag(.call_options_type),
.inferred_alloc_const => unreachable,
.inferred_alloc_mut => unreachable,
else => return Value.Tag.ty.create(allocator, self),
@@ -1001,6 +1057,14 @@ pub const Type = extern union {
.anyerror_void_error_union,
.error_set,
.error_set_single,
+ .manyptr_u8,
+ .manyptr_const_u8,
+ .atomic_ordering,
+ .atomic_rmw_op,
+ .calling_convention,
+ .float_mode,
+ .reduce_op,
+ .call_options,
=> true,
.@"struct" => {
@@ -1079,7 +1143,10 @@ pub const Type = extern union {
.optional_single_mut_pointer,
=> return self.cast(Payload.ElemType).?.data.abiAlignment(target),
- .const_slice_u8 => return 1,
+ .manyptr_u8,
+ .manyptr_const_u8,
+ .const_slice_u8,
+ => return 1,
.pointer => {
const ptr_info = self.castTag(.pointer).?.data;
@@ -1102,6 +1169,12 @@ pub const Type = extern union {
.bool,
.array_u8_sentinel_0,
.array_u8,
+ .atomic_ordering,
+ .atomic_rmw_op,
+ .calling_convention,
+ .float_mode,
+ .reduce_op,
+ .call_options,
=> return 1,
.fn_noreturn_no_args, // represents machine code; not a pointer
@@ -1136,6 +1209,8 @@ pub const Type = extern union {
.optional_single_const_pointer,
.optional_single_mut_pointer,
.pointer,
+ .manyptr_u8,
+ .manyptr_const_u8,
=> return @divExact(target.cpu.arch.ptrBitWidth(), 8),
.c_short => return @divExact(CType.short.sizeInBits(target), 8),
@@ -1271,6 +1346,12 @@ pub const Type = extern union {
.u8,
.i8,
.bool,
+ .atomic_ordering,
+ .atomic_rmw_op,
+ .calling_convention,
+ .float_mode,
+ .reduce_op,
+ .call_options,
=> return 1,
.array_u8 => self.castTag(.array_u8).?.data,
@@ -1322,6 +1403,10 @@ pub const Type = extern union {
return @divExact(target.cpu.arch.ptrBitWidth(), 8);
},
+ .manyptr_u8,
+ .manyptr_const_u8,
+ => return @divExact(target.cpu.arch.ptrBitWidth(), 8),
+
.c_short => return @divExact(CType.short.sizeInBits(target), 8),
.c_ushort => return @divExact(CType.ushort.sizeInBits(target), 8),
.c_int => return @divExact(CType.int.sizeInBits(target), 8),
@@ -1475,6 +1560,10 @@ pub const Type = extern union {
}
},
+ .manyptr_u8,
+ .manyptr_const_u8,
+ => return target.cpu.arch.ptrBitWidth(),
+
.c_short => return CType.short.sizeInBits(target),
.c_ushort => return CType.ushort.sizeInBits(target),
.c_int => return CType.int.sizeInBits(target),
@@ -1517,8 +1606,16 @@ pub const Type = extern union {
} else if (!payload.payload.hasCodeGenBits()) {
return payload.error_set.bitSize(target);
}
- @panic("TODO abiSize error union");
+ @panic("TODO bitSize error union");
},
+
+ .atomic_ordering,
+ .atomic_rmw_op,
+ .calling_convention,
+ .float_mode,
+ .reduce_op,
+ .call_options,
+ => @panic("TODO at some point we gotta resolve builtin types"),
};
}
@@ -1564,6 +1661,8 @@ pub const Type = extern union {
.many_const_pointer,
.many_mut_pointer,
+ .manyptr_u8,
+ .manyptr_const_u8,
=> .Many,
.c_const_pointer,
@@ -1604,6 +1703,7 @@ pub const Type = extern union {
.single_const_pointer_to_comptime_int,
.const_slice_u8,
.const_slice,
+ .manyptr_const_u8,
=> true,
.pointer => !self.castTag(.pointer).?.data.mutable,
@@ -1718,7 +1818,13 @@ pub const Type = extern union {
.mut_slice,
=> self.castPointer().?.data,
- .array_u8, .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8),
+ .array_u8,
+ .array_u8_sentinel_0,
+ .const_slice_u8,
+ .manyptr_u8,
+ .manyptr_const_u8,
+ => Type.initTag(.u8),
+
.single_const_pointer_to_comptime_int => Type.initTag(.comptime_int),
.pointer => self.castTag(.pointer).?.data.pointee_type,
@@ -1811,6 +1917,8 @@ pub const Type = extern union {
.single_const_pointer_to_comptime_int,
.array,
.array_u8,
+ .manyptr_u8,
+ .manyptr_const_u8,
=> return null,
.pointer => return self.castTag(.pointer).?.data.sentinel,
@@ -2122,6 +2230,14 @@ pub const Type = extern union {
.error_set_single,
.@"opaque",
.var_args_param,
+ .manyptr_u8,
+ .manyptr_const_u8,
+ .atomic_ordering,
+ .atomic_rmw_op,
+ .calling_convention,
+ .float_mode,
+ .reduce_op,
+ .call_options,
=> return null,
.@"struct" => {
@@ -2281,6 +2397,14 @@ pub const Type = extern union {
const enum_simple = ty.castTag(.enum_simple).?.data;
return enum_simple.fields.count();
},
+ .atomic_ordering,
+ .atomic_rmw_op,
+ .calling_convention,
+ .float_mode,
+ .reduce_op,
+ .call_options,
+ => @panic("TODO resolve std.builtin types"),
+
else => unreachable,
}
}
@@ -2295,6 +2419,13 @@ pub const Type = extern union {
const enum_simple = ty.castTag(.enum_simple).?.data;
return enum_simple.fields.entries.items[field_index].key;
},
+ .atomic_ordering,
+ .atomic_rmw_op,
+ .calling_convention,
+ .float_mode,
+ .reduce_op,
+ .call_options,
+ => @panic("TODO resolve std.builtin types"),
else => unreachable,
}
}
@@ -2309,6 +2440,13 @@ pub const Type = extern union {
const enum_simple = ty.castTag(.enum_simple).?.data;
return enum_simple.fields.getIndex(field_name);
},
+ .atomic_ordering,
+ .atomic_rmw_op,
+ .calling_convention,
+ .float_mode,
+ .reduce_op,
+ .call_options,
+ => @panic("TODO resolve std.builtin types"),
else => unreachable,
}
}
@@ -2345,6 +2483,13 @@ pub const Type = extern union {
const enum_simple = ty.castTag(.enum_simple).?.data;
return S.fieldWithRange(enum_tag, enum_simple.fields.count());
},
+ .atomic_ordering,
+ .atomic_rmw_op,
+ .calling_convention,
+ .float_mode,
+ .reduce_op,
+ .call_options,
+ => @panic("TODO resolve std.builtin types"),
else => unreachable,
}
}
@@ -2367,6 +2512,13 @@ pub const Type = extern union {
const error_set = ty.castTag(.error_set).?.data;
return error_set.srcLoc();
},
+ .atomic_ordering,
+ .atomic_rmw_op,
+ .calling_convention,
+ .float_mode,
+ .reduce_op,
+ .call_options,
+ => @panic("TODO resolve std.builtin types"),
else => unreachable,
}
}
@@ -2390,6 +2542,13 @@ pub const Type = extern union {
return error_set.owner_decl;
},
.@"opaque" => @panic("TODO"),
+ .atomic_ordering,
+ .atomic_rmw_op,
+ .calling_convention,
+ .float_mode,
+ .reduce_op,
+ .call_options,
+ => @panic("TODO resolve std.builtin types"),
else => unreachable,
}
}
@@ -2422,6 +2581,13 @@ pub const Type = extern union {
const enum_simple = ty.castTag(.enum_simple).?.data;
return S.intInRange(int, enum_simple.fields.count());
},
+ .atomic_ordering,
+ .atomic_rmw_op,
+ .calling_convention,
+ .float_mode,
+ .reduce_op,
+ .call_options,
+ => @panic("TODO resolve std.builtin types"),
else => unreachable,
}
@@ -2469,6 +2635,14 @@ pub const Type = extern union {
comptime_float,
noreturn,
enum_literal,
+ manyptr_u8,
+ manyptr_const_u8,
+ atomic_ordering,
+ atomic_rmw_op,
+ calling_convention,
+ float_mode,
+ reduce_op,
+ call_options,
@"null",
@"undefined",
fn_noreturn_no_args,
@@ -2572,6 +2746,14 @@ pub const Type = extern union {
.inferred_alloc_mut,
.var_args_param,
.empty_struct_literal,
+ .manyptr_u8,
+ .manyptr_const_u8,
+ .atomic_ordering,
+ .atomic_rmw_op,
+ .calling_convention,
+ .float_mode,
+ .reduce_op,
+ .call_options,
=> @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),
.array_u8,
diff --git a/src/value.zig b/src/value.zig
index a9aec47272..80b21f0713 100644
--- a/src/value.zig
+++ b/src/value.zig
@@ -64,6 +64,14 @@ pub const Value = extern union {
single_const_pointer_to_comptime_int_type,
const_slice_u8_type,
enum_literal_type,
+ manyptr_u8_type,
+ manyptr_const_u8_type,
+ atomic_ordering_type,
+ atomic_rmw_op_type,
+ calling_convention_type,
+ float_mode_type,
+ reduce_op_type,
+ call_options_type,
undef,
zero,
@@ -169,6 +177,14 @@ pub const Value = extern union {
.bool_true,
.bool_false,
.abi_align_default,
+ .manyptr_u8_type,
+ .manyptr_const_u8_type,
+ .atomic_ordering_type,
+ .atomic_rmw_op_type,
+ .calling_convention_type,
+ .float_mode_type,
+ .reduce_op_type,
+ .call_options_type,
=> @compileError("Value Tag " ++ @tagName(t) ++ " has no payload"),
.int_big_positive,
@@ -327,6 +343,14 @@ pub const Value = extern union {
.bool_false,
.empty_struct_value,
.abi_align_default,
+ .manyptr_u8_type,
+ .manyptr_const_u8_type,
+ .atomic_ordering_type,
+ .atomic_rmw_op_type,
+ .calling_convention_type,
+ .float_mode_type,
+ .reduce_op_type,
+ .call_options_type,
=> unreachable,
.ty => {
@@ -474,6 +498,14 @@ pub const Value = extern union {
.single_const_pointer_to_comptime_int_type => return out_stream.writeAll("*const comptime_int"),
.const_slice_u8_type => return out_stream.writeAll("[]const u8"),
.enum_literal_type => return out_stream.writeAll("@Type(.EnumLiteral)"),
+ .manyptr_u8_type => return out_stream.writeAll("[*]u8"),
+ .manyptr_const_u8_type => return out_stream.writeAll("[*]const u8"),
+ .atomic_ordering_type => return out_stream.writeAll("std.builtin.AtomicOrdering"),
+ .atomic_rmw_op_type => return out_stream.writeAll("std.builtin.AtomicRmwOp"),
+ .calling_convention_type => return out_stream.writeAll("std.builtin.CallingConvention"),
+ .float_mode_type => return out_stream.writeAll("std.builtin.FloatMode"),
+ .reduce_op_type => return out_stream.writeAll("std.builtin.ReduceOp"),
+ .call_options_type => return out_stream.writeAll("std.builtin.CallOptions"),
.abi_align_default => return out_stream.writeAll("(default ABI alignment)"),
.empty_struct_value => return out_stream.writeAll("struct {}{}"),
@@ -595,6 +627,14 @@ pub const Value = extern union {
.single_const_pointer_to_comptime_int_type => Type.initTag(.single_const_pointer_to_comptime_int),
.const_slice_u8_type => Type.initTag(.const_slice_u8),
.enum_literal_type => Type.initTag(.enum_literal),
+ .manyptr_u8_type => Type.initTag(.manyptr_u8),
+ .manyptr_const_u8_type => Type.initTag(.manyptr_const_u8),
+ .atomic_ordering_type => Type.initTag(.atomic_ordering),
+ .atomic_rmw_op_type => Type.initTag(.atomic_rmw_op),
+ .calling_convention_type => Type.initTag(.calling_convention),
+ .float_mode_type => Type.initTag(.float_mode),
+ .reduce_op_type => Type.initTag(.reduce_op),
+ .call_options_type => Type.initTag(.call_options),
.int_type => {
const payload = self.castTag(.int_type).?.data;
@@ -1132,6 +1172,16 @@ pub const Value = extern union {
std.hash.autoHash(&hasher, payload.hash());
},
.inferred_alloc => unreachable,
+
+ .manyptr_u8_type,
+ .manyptr_const_u8_type,
+ .atomic_ordering_type,
+ .atomic_rmw_op_type,
+ .calling_convention_type,
+ .float_mode_type,
+ .reduce_op_type,
+ .call_options_type,
+ => @panic("TODO this hash function looks pretty broken. audit it"),
}
return hasher.final();
}
@@ -1278,6 +1328,14 @@ pub const Value = extern union {
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.enum_literal_type,
+ .manyptr_u8_type,
+ .manyptr_const_u8_type,
+ .atomic_ordering_type,
+ .atomic_rmw_op_type,
+ .calling_convention_type,
+ .float_mode_type,
+ .reduce_op_type,
+ .call_options_type,
=> true,
.zero,