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