mirror of
https://github.com/ziglang/zig.git
synced 2026-01-18 05:15:18 +00:00
AstGen: implement opaque decls
Also move the decls to the beginning in ZIR encoding because in Sema we want to create the namespace with the decls before evaluating the fields.
This commit is contained in:
parent
56226449d2
commit
646eb1fa93
138
src/AstGen.zig
138
src/AstGen.zig
@ -3254,6 +3254,12 @@ fn structDeclInner(
|
||||
.fields_len = @intCast(u32, field_index),
|
||||
.decls_len = @intCast(u32, wip_decls.decl_index),
|
||||
});
|
||||
astgen.extra.appendSliceAssumeCapacity(wip_decls.bit_bag.items); // Likely empty.
|
||||
if (wip_decls.decl_index != 0) {
|
||||
astgen.extra.appendAssumeCapacity(wip_decls.cur_bit_bag);
|
||||
}
|
||||
astgen.extra.appendSliceAssumeCapacity(wip_decls.payload.items);
|
||||
|
||||
astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items);
|
||||
|
||||
astgen.extra.appendSliceAssumeCapacity(bit_bag.items); // Likely empty.
|
||||
@ -3262,12 +3268,6 @@ fn structDeclInner(
|
||||
}
|
||||
astgen.extra.appendSliceAssumeCapacity(fields_data.items);
|
||||
|
||||
astgen.extra.appendSliceAssumeCapacity(wip_decls.bit_bag.items); // Likely empty.
|
||||
if (wip_decls.decl_index != 0) {
|
||||
astgen.extra.appendAssumeCapacity(wip_decls.cur_bit_bag);
|
||||
}
|
||||
astgen.extra.appendSliceAssumeCapacity(wip_decls.payload.items);
|
||||
|
||||
return gz.indexToRef(decl_inst);
|
||||
}
|
||||
|
||||
@ -3479,18 +3479,18 @@ fn unionDeclInner(
|
||||
.fields_len = @intCast(u32, field_index),
|
||||
.decls_len = @intCast(u32, wip_decls.decl_index),
|
||||
});
|
||||
astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items);
|
||||
|
||||
astgen.extra.appendSliceAssumeCapacity(bit_bag.items); // Likely empty.
|
||||
astgen.extra.appendAssumeCapacity(cur_bit_bag);
|
||||
astgen.extra.appendSliceAssumeCapacity(fields_data.items);
|
||||
|
||||
astgen.extra.appendSliceAssumeCapacity(wip_decls.bit_bag.items); // Likely empty.
|
||||
if (wip_decls.decl_index != 0) {
|
||||
astgen.extra.appendAssumeCapacity(wip_decls.cur_bit_bag);
|
||||
}
|
||||
astgen.extra.appendSliceAssumeCapacity(wip_decls.payload.items);
|
||||
|
||||
astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items);
|
||||
|
||||
astgen.extra.appendSliceAssumeCapacity(bit_bag.items); // Likely empty.
|
||||
astgen.extra.appendAssumeCapacity(cur_bit_bag);
|
||||
astgen.extra.appendSliceAssumeCapacity(fields_data.items);
|
||||
|
||||
return gz.indexToRef(decl_inst);
|
||||
}
|
||||
|
||||
@ -3811,11 +3811,121 @@ fn containerDecl(
|
||||
.fields_len = @intCast(u32, field_index),
|
||||
.decls_len = @intCast(u32, wip_decls.decl_index),
|
||||
});
|
||||
astgen.extra.appendSliceAssumeCapacity(wip_decls.bit_bag.items); // Likely empty.
|
||||
if (wip_decls.decl_index != 0) {
|
||||
astgen.extra.appendAssumeCapacity(wip_decls.cur_bit_bag);
|
||||
}
|
||||
astgen.extra.appendSliceAssumeCapacity(wip_decls.payload.items);
|
||||
|
||||
astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items);
|
||||
astgen.extra.appendSliceAssumeCapacity(bit_bag.items); // Likely empty.
|
||||
astgen.extra.appendAssumeCapacity(cur_bit_bag);
|
||||
astgen.extra.appendSliceAssumeCapacity(fields_data.items);
|
||||
|
||||
return rvalue(gz, scope, rl, gz.indexToRef(decl_inst), node);
|
||||
},
|
||||
.keyword_opaque => {
|
||||
var wip_decls: WipDecls = .{};
|
||||
defer wip_decls.deinit(gpa);
|
||||
|
||||
for (container_decl.ast.members) |member_node| {
|
||||
const member = switch (node_tags[member_node]) {
|
||||
.container_field_init => tree.containerFieldInit(member_node),
|
||||
.container_field_align => tree.containerFieldAlign(member_node),
|
||||
.container_field => tree.containerField(member_node),
|
||||
|
||||
.fn_decl => {
|
||||
const fn_proto = node_datas[member_node].lhs;
|
||||
const body = node_datas[member_node].rhs;
|
||||
switch (node_tags[fn_proto]) {
|
||||
.fn_proto_simple => {
|
||||
var params: [1]ast.Node.Index = undefined;
|
||||
try astgen.fnDecl(gz, &wip_decls, body, tree.fnProtoSimple(¶ms, fn_proto));
|
||||
continue;
|
||||
},
|
||||
.fn_proto_multi => {
|
||||
try astgen.fnDecl(gz, &wip_decls, body, tree.fnProtoMulti(fn_proto));
|
||||
continue;
|
||||
},
|
||||
.fn_proto_one => {
|
||||
var params: [1]ast.Node.Index = undefined;
|
||||
try astgen.fnDecl(gz, &wip_decls, body, tree.fnProtoOne(¶ms, fn_proto));
|
||||
continue;
|
||||
},
|
||||
.fn_proto => {
|
||||
try astgen.fnDecl(gz, &wip_decls, body, tree.fnProto(fn_proto));
|
||||
continue;
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
},
|
||||
.fn_proto_simple => {
|
||||
var params: [1]ast.Node.Index = undefined;
|
||||
try astgen.fnDecl(gz, &wip_decls, 0, tree.fnProtoSimple(¶ms, member_node));
|
||||
continue;
|
||||
},
|
||||
.fn_proto_multi => {
|
||||
try astgen.fnDecl(gz, &wip_decls, 0, tree.fnProtoMulti(member_node));
|
||||
continue;
|
||||
},
|
||||
.fn_proto_one => {
|
||||
var params: [1]ast.Node.Index = undefined;
|
||||
try astgen.fnDecl(gz, &wip_decls, 0, tree.fnProtoOne(¶ms, member_node));
|
||||
continue;
|
||||
},
|
||||
.fn_proto => {
|
||||
try astgen.fnDecl(gz, &wip_decls, 0, tree.fnProto(member_node));
|
||||
continue;
|
||||
},
|
||||
|
||||
.global_var_decl => {
|
||||
try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.globalVarDecl(member_node));
|
||||
continue;
|
||||
},
|
||||
.local_var_decl => {
|
||||
try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.localVarDecl(member_node));
|
||||
continue;
|
||||
},
|
||||
.simple_var_decl => {
|
||||
try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.simpleVarDecl(member_node));
|
||||
continue;
|
||||
},
|
||||
.aligned_var_decl => {
|
||||
try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.alignedVarDecl(member_node));
|
||||
continue;
|
||||
},
|
||||
|
||||
.@"comptime" => {
|
||||
try astgen.comptimeDecl(gz, scope, member_node);
|
||||
continue;
|
||||
},
|
||||
.@"usingnamespace" => {
|
||||
try astgen.usingnamespaceDecl(gz, scope, member_node);
|
||||
continue;
|
||||
},
|
||||
.test_decl => {
|
||||
try astgen.testDecl(gz, scope, member_node);
|
||||
continue;
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
{
|
||||
const empty_slot_count = WipDecls.fields_per_u32 - (wip_decls.decl_index % WipDecls.fields_per_u32);
|
||||
if (empty_slot_count < WipDecls.fields_per_u32) {
|
||||
wip_decls.cur_bit_bag >>= @intCast(u5, empty_slot_count * WipDecls.bits_per_field);
|
||||
}
|
||||
}
|
||||
const decl_inst = try gz.addBlock(.opaque_decl, node);
|
||||
try gz.instructions.append(gpa, decl_inst);
|
||||
|
||||
try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.OpaqueDecl).Struct.fields.len +
|
||||
wip_decls.bit_bag.items.len + @boolToInt(wip_decls.decl_index != 0) +
|
||||
wip_decls.payload.items.len);
|
||||
const zir_datas = astgen.instructions.items(.data);
|
||||
zir_datas[decl_inst].pl_node.payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.OpaqueDecl{
|
||||
.decls_len = @intCast(u32, wip_decls.decl_index),
|
||||
});
|
||||
astgen.extra.appendSliceAssumeCapacity(wip_decls.bit_bag.items); // Likely empty.
|
||||
if (wip_decls.decl_index != 0) {
|
||||
astgen.extra.appendAssumeCapacity(wip_decls.cur_bit_bag);
|
||||
@ -3824,10 +3934,6 @@ fn containerDecl(
|
||||
|
||||
return rvalue(gz, scope, rl, gz.indexToRef(decl_inst), node);
|
||||
},
|
||||
.keyword_opaque => {
|
||||
const result = try gz.addNode(.opaque_decl, node);
|
||||
return rvalue(gz, scope, rl, result, node);
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
236
src/Zir.zig
236
src/Zir.zig
@ -312,7 +312,7 @@ pub const Inst = struct {
|
||||
/// Same as `enum_decl`, except the enum is non-exhaustive.
|
||||
enum_decl_nonexhaustive,
|
||||
/// An opaque type definition. Provides an AST node only.
|
||||
/// Uses the `node` union field.
|
||||
/// Uses the `pl_node` union field. Payload is `OpaqueDecl`.
|
||||
opaque_decl,
|
||||
/// An error set type definition. Contains a list of field names.
|
||||
/// Uses the `pl_node` union field. Payload is `ErrorSetDecl`.
|
||||
@ -2368,29 +2368,29 @@ pub const Inst = struct {
|
||||
};
|
||||
|
||||
/// Trailing:
|
||||
/// 0. inst: Index // for every body_len
|
||||
/// 1. has_bits: u32 // for every 16 fields
|
||||
/// - sets of 2 bits:
|
||||
/// 0b0X: whether corresponding field has an align expression
|
||||
/// 0bX0: whether corresponding field has a default expression
|
||||
/// 2. fields: { // for every fields_len
|
||||
/// field_name: u32,
|
||||
/// field_type: Ref,
|
||||
/// align: Ref, // if corresponding bit is set
|
||||
/// default_value: Ref, // if corresponding bit is set
|
||||
/// }
|
||||
/// 3. decl_bits: u32 // for every 8 decls
|
||||
/// 0. decl_bits: u32 // for every 8 decls
|
||||
/// - sets of 4 bits:
|
||||
/// 0b000X: whether corresponding decl is pub
|
||||
/// 0b00X0: whether corresponding decl is exported
|
||||
/// 0b0X00: whether corresponding decl has an align expression
|
||||
/// 0bX000: whether corresponding decl has a linksection expression
|
||||
/// 4. decl: { // for every decls_len
|
||||
/// 1. decl: { // for every decls_len
|
||||
/// name: u32, // null terminated string index
|
||||
/// value: Index,
|
||||
/// align: Ref, // if corresponding bit is set
|
||||
/// link_section: Ref, // if corresponding bit is set
|
||||
/// }
|
||||
/// 2. inst: Index // for every body_len
|
||||
/// 3. has_bits: u32 // for every 16 fields
|
||||
/// - sets of 2 bits:
|
||||
/// 0b0X: whether corresponding field has an align expression
|
||||
/// 0bX0: whether corresponding field has a default expression
|
||||
/// 4. fields: { // for every fields_len
|
||||
/// field_name: u32,
|
||||
/// field_type: Ref,
|
||||
/// align: Ref, // if corresponding bit is set
|
||||
/// default_value: Ref, // if corresponding bit is set
|
||||
/// }
|
||||
pub const StructDecl = struct {
|
||||
body_len: u32,
|
||||
fields_len: u32,
|
||||
@ -2398,25 +2398,25 @@ pub const Inst = struct {
|
||||
};
|
||||
|
||||
/// Trailing:
|
||||
/// 0. inst: Index // for every body_len
|
||||
/// 1. has_bits: u32 // for every 32 fields
|
||||
/// - the bit is whether corresponding field has an value expression
|
||||
/// 2. fields: { // for every fields_len
|
||||
/// field_name: u32,
|
||||
/// value: Ref, // if corresponding bit is set
|
||||
/// }
|
||||
/// 3. decl_bits: u32 // for every 8 decls
|
||||
/// 0. decl_bits: u32 // for every 8 decls
|
||||
/// - sets of 4 bits:
|
||||
/// 0b000X: whether corresponding decl is pub
|
||||
/// 0b00X0: whether corresponding decl is exported
|
||||
/// 0b0X00: whether corresponding decl has an align expression
|
||||
/// 0bX000: whether corresponding decl has a linksection expression
|
||||
/// 4. decl: { // for every decls_len
|
||||
/// 1. decl: { // for every decls_len
|
||||
/// name: u32, // null terminated string index
|
||||
/// value: Index,
|
||||
/// align: Ref, // if corresponding bit is set
|
||||
/// link_section: Ref, // if corresponding bit is set
|
||||
/// }
|
||||
/// 2. inst: Index // for every body_len
|
||||
/// 3. has_bits: u32 // for every 32 fields
|
||||
/// - the bit is whether corresponding field has an value expression
|
||||
/// 4. fields: { // for every fields_len
|
||||
/// field_name: u32,
|
||||
/// value: Ref, // if corresponding bit is set
|
||||
/// }
|
||||
pub const EnumDecl = struct {
|
||||
/// Can be `Ref.none`.
|
||||
tag_type: Ref,
|
||||
@ -2426,8 +2426,20 @@ pub const Inst = struct {
|
||||
};
|
||||
|
||||
/// Trailing:
|
||||
/// 0. inst: Index // for every body_len
|
||||
/// 1. has_bits: u32 // for every 8 fields
|
||||
/// 0. decl_bits: u32 // for every 8 decls
|
||||
/// - sets of 4 bits:
|
||||
/// 0b000X: whether corresponding decl is pub
|
||||
/// 0b00X0: whether corresponding decl is exported
|
||||
/// 0b0X00: whether corresponding decl has an align expression
|
||||
/// 0bX000: whether corresponding decl has a linksection expression
|
||||
/// 1. decl: { // for every decls_len
|
||||
/// name: u32, // null terminated string index
|
||||
/// value: Index,
|
||||
/// align: Ref, // if corresponding bit is set
|
||||
/// link_section: Ref, // if corresponding bit is set
|
||||
/// }
|
||||
/// 2. inst: Index // for every body_len
|
||||
/// 3. has_bits: u32 // for every 8 fields
|
||||
/// - sets of 4 bits:
|
||||
/// 0b000X: whether corresponding field has a type expression
|
||||
/// 0b00X0: whether corresponding field has a align expression
|
||||
@ -2437,24 +2449,12 @@ pub const Inst = struct {
|
||||
/// to indicate whether auto enum tag is enabled.
|
||||
/// 0 = union(tag_type)
|
||||
/// 1 = union(enum(tag_type))
|
||||
/// 2. fields: { // for every fields_len
|
||||
/// 4. fields: { // for every fields_len
|
||||
/// field_name: u32, // null terminated string index
|
||||
/// field_type: Ref, // if corresponding bit is set
|
||||
/// align: Ref, // if corresponding bit is set
|
||||
/// tag_value: Ref, // if corresponding bit is set
|
||||
/// }
|
||||
/// 3. decl_bits: u32 // for every 8 decls
|
||||
/// - sets of 4 bits:
|
||||
/// 0b000X: whether corresponding decl is pub
|
||||
/// 0b00X0: whether corresponding decl is exported
|
||||
/// 0b0X00: whether corresponding decl has an align expression
|
||||
/// 0bX000: whether corresponding decl has a linksection expression
|
||||
/// 4. decl: { // for every decls_len
|
||||
/// name: u32, // null terminated string index
|
||||
/// value: Index,
|
||||
/// align: Ref, // if corresponding bit is set
|
||||
/// link_section: Ref, // if corresponding bit is set
|
||||
/// }
|
||||
pub const UnionDecl = struct {
|
||||
/// Can be `Ref.none`.
|
||||
tag_type: Ref,
|
||||
@ -2463,6 +2463,23 @@ pub const Inst = struct {
|
||||
decls_len: u32,
|
||||
};
|
||||
|
||||
/// Trailing:
|
||||
/// 0. decl_bits: u32 // for every 8 decls
|
||||
/// - sets of 4 bits:
|
||||
/// 0b000X: whether corresponding decl is pub
|
||||
/// 0b00X0: whether corresponding decl is exported
|
||||
/// 0b0X00: whether corresponding decl has an align expression
|
||||
/// 0bX000: whether corresponding decl has a linksection expression
|
||||
/// 1. decl: { // for every decls_len
|
||||
/// name: u32, // null terminated string index
|
||||
/// value: Index,
|
||||
/// align: Ref, // if corresponding bit is set
|
||||
/// link_section: Ref, // if corresponding bit is set
|
||||
/// }
|
||||
pub const OpaqueDecl = struct {
|
||||
decls_len: u32,
|
||||
};
|
||||
|
||||
/// Trailing: field_name: u32 // for every field: null terminated string index
|
||||
pub const ErrorSetDecl = struct {
|
||||
fields_len: u32,
|
||||
@ -2897,6 +2914,8 @@ const Writer = struct {
|
||||
.enum_decl_nonexhaustive,
|
||||
=> try self.writeEnumDecl(stream, inst),
|
||||
|
||||
.opaque_decl => try self.writeOpaqueDecl(stream, inst),
|
||||
|
||||
.switch_block => try self.writePlNodeSwitchBr(stream, inst, .none),
|
||||
.switch_block_else => try self.writePlNodeSwitchBr(stream, inst, .@"else"),
|
||||
.switch_block_under => try self.writePlNodeSwitchBr(stream, inst, .under),
|
||||
@ -2919,7 +2938,6 @@ const Writer = struct {
|
||||
|
||||
.breakpoint,
|
||||
.fence,
|
||||
.opaque_decl,
|
||||
.dbg_stmt_node,
|
||||
.repeat,
|
||||
.repeat_inline,
|
||||
@ -3321,27 +3339,45 @@ const Writer = struct {
|
||||
fn writeStructDecl(self: *Writer, stream: anytype, inst: Inst.Index) !void {
|
||||
const inst_data = self.code.instructions.items(.data)[inst].pl_node;
|
||||
const extra = self.code.extraData(Inst.StructDecl, inst_data.payload_index);
|
||||
const body = self.code.extra[extra.end..][0..extra.data.body_len];
|
||||
const fields_len = extra.data.fields_len;
|
||||
const decls_len = extra.data.decls_len;
|
||||
|
||||
var extra_index: usize = undefined;
|
||||
|
||||
if (decls_len == 0) {
|
||||
try stream.writeAll("}) ");
|
||||
extra_index = extra.end;
|
||||
} else {
|
||||
try stream.writeAll("\n");
|
||||
self.indent += 2;
|
||||
extra_index = try self.writeDecls(stream, decls_len, extra.end);
|
||||
self.indent -= 2;
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try stream.writeAll("}) ");
|
||||
}
|
||||
|
||||
const body = self.code.extra[extra_index..][0..extra.data.body_len];
|
||||
extra_index += body.len;
|
||||
|
||||
if (fields_len == 0) {
|
||||
assert(body.len == 0);
|
||||
try stream.writeAll("{}, {}, {");
|
||||
extra_index = extra.end;
|
||||
} else {
|
||||
try stream.writeAll("{\n");
|
||||
self.indent += 2;
|
||||
try self.writeBody(stream, body);
|
||||
if (body.len == 0) {
|
||||
try stream.writeAll("{}, {\n");
|
||||
} else {
|
||||
try stream.writeAll("{\n");
|
||||
try self.writeBody(stream, body);
|
||||
|
||||
try stream.writeByteNTimes(' ', self.indent - 2);
|
||||
try stream.writeAll("}, {\n");
|
||||
try stream.writeByteNTimes(' ', self.indent - 2);
|
||||
try stream.writeAll("}, {\n");
|
||||
}
|
||||
|
||||
const bit_bags_count = std.math.divCeil(usize, fields_len, 16) catch unreachable;
|
||||
const body_end = extra.end + body.len;
|
||||
extra_index = body_end + bit_bags_count;
|
||||
const body_end = extra_index;
|
||||
extra_index += bit_bags_count;
|
||||
var bit_bag_index: usize = body_end;
|
||||
var cur_bit_bag: u32 = undefined;
|
||||
var field_i: u32 = 0;
|
||||
@ -3386,27 +3422,30 @@ const Writer = struct {
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try stream.writeAll("}, {");
|
||||
}
|
||||
if (decls_len == 0) {
|
||||
try stream.writeAll("}) ");
|
||||
} else {
|
||||
try stream.writeAll("\n");
|
||||
self.indent += 2;
|
||||
try self.writeDecls(stream, decls_len, extra_index);
|
||||
self.indent -= 2;
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try stream.writeAll("}) ");
|
||||
}
|
||||
try self.writeSrc(stream, inst_data.src());
|
||||
}
|
||||
|
||||
fn writeUnionDecl(self: *Writer, stream: anytype, inst: Inst.Index) !void {
|
||||
const inst_data = self.code.instructions.items(.data)[inst].pl_node;
|
||||
const extra = self.code.extraData(Inst.UnionDecl, inst_data.payload_index);
|
||||
const body = self.code.extra[extra.end..][0..extra.data.body_len];
|
||||
const fields_len = extra.data.fields_len;
|
||||
const decls_len = extra.data.decls_len;
|
||||
const tag_type_ref = extra.data.tag_type;
|
||||
|
||||
var extra_index: usize = undefined;
|
||||
|
||||
if (decls_len == 0) {
|
||||
try stream.writeAll("{}, ");
|
||||
extra_index = extra.end;
|
||||
} else {
|
||||
try stream.writeAll("{\n");
|
||||
self.indent += 2;
|
||||
extra_index = try self.writeDecls(stream, decls_len, extra.end);
|
||||
self.indent -= 2;
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try stream.writeAll("}, ");
|
||||
}
|
||||
|
||||
assert(fields_len != 0);
|
||||
var first_has_auto_enum: ?bool = null;
|
||||
|
||||
@ -3415,20 +3454,25 @@ const Writer = struct {
|
||||
try stream.writeAll(", ");
|
||||
}
|
||||
|
||||
var extra_index: usize = undefined;
|
||||
const body = self.code.extra[extra_index..][0..extra.data.body_len];
|
||||
extra_index += body.len;
|
||||
|
||||
try stream.writeAll("{\n");
|
||||
self.indent += 2;
|
||||
try self.writeBody(stream, body);
|
||||
if (body.len == 0) {
|
||||
try stream.writeAll("{}, {\n");
|
||||
} else {
|
||||
try stream.writeAll("{\n");
|
||||
try self.writeBody(stream, body);
|
||||
|
||||
try stream.writeByteNTimes(' ', self.indent - 2);
|
||||
try stream.writeAll("}, {\n");
|
||||
try stream.writeByteNTimes(' ', self.indent - 2);
|
||||
try stream.writeAll("}, {\n");
|
||||
}
|
||||
|
||||
const bits_per_field = 4;
|
||||
const fields_per_u32 = 32 / bits_per_field;
|
||||
const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;
|
||||
const body_end = extra.end + body.len;
|
||||
extra_index = body_end + bit_bags_count;
|
||||
const body_end = extra_index;
|
||||
extra_index += bit_bags_count;
|
||||
var bit_bag_index: usize = body_end;
|
||||
var cur_bit_bag: u32 = undefined;
|
||||
var field_i: u32 = 0;
|
||||
@ -3482,23 +3526,13 @@ const Writer = struct {
|
||||
|
||||
self.indent -= 2;
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try stream.writeAll("}, {");
|
||||
if (decls_len == 0) {
|
||||
try stream.writeAll("}");
|
||||
} else {
|
||||
try stream.writeAll("\n");
|
||||
self.indent += 2;
|
||||
try self.writeDecls(stream, decls_len, extra_index);
|
||||
self.indent -= 2;
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try stream.writeAll("}");
|
||||
}
|
||||
try stream.writeAll("}");
|
||||
try self.writeFlag(stream, ", autoenum", first_has_auto_enum.?);
|
||||
try stream.writeAll(") ");
|
||||
try self.writeSrc(stream, inst_data.src());
|
||||
}
|
||||
|
||||
fn writeDecls(self: *Writer, stream: anytype, decls_len: u32, extra_start: usize) !void {
|
||||
fn writeDecls(self: *Writer, stream: anytype, decls_len: u32, extra_start: usize) !usize {
|
||||
const parent_decl_node = self.parent_decl_node;
|
||||
const bit_bags_count = std.math.divCeil(usize, decls_len, 8) catch unreachable;
|
||||
var extra_index = extra_start + bit_bags_count;
|
||||
@ -3561,38 +3595,56 @@ const Writer = struct {
|
||||
try self.writeSrc(stream, decl_block_inst_data.src());
|
||||
try stream.writeAll("\n");
|
||||
}
|
||||
return extra_index;
|
||||
}
|
||||
|
||||
fn writeEnumDecl(self: *Writer, stream: anytype, inst: Inst.Index) !void {
|
||||
const inst_data = self.code.instructions.items(.data)[inst].pl_node;
|
||||
const extra = self.code.extraData(Inst.EnumDecl, inst_data.payload_index);
|
||||
const body = self.code.extra[extra.end..][0..extra.data.body_len];
|
||||
const fields_len = extra.data.fields_len;
|
||||
const decls_len = extra.data.decls_len;
|
||||
const tag_type_ref = extra.data.tag_type;
|
||||
|
||||
var extra_index: usize = undefined;
|
||||
|
||||
if (decls_len == 0) {
|
||||
try stream.writeAll("{}, ");
|
||||
extra_index = extra.end;
|
||||
} else {
|
||||
try stream.writeAll("{\n");
|
||||
self.indent += 2;
|
||||
extra_index = try self.writeDecls(stream, decls_len, extra.end);
|
||||
self.indent -= 2;
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try stream.writeAll("}, ");
|
||||
}
|
||||
|
||||
if (tag_type_ref != .none) {
|
||||
try self.writeInstRef(stream, tag_type_ref);
|
||||
try stream.writeAll(", ");
|
||||
}
|
||||
|
||||
var extra_index: usize = undefined;
|
||||
const body = self.code.extra[extra_index..][0..extra.data.body_len];
|
||||
extra_index += body.len;
|
||||
|
||||
if (fields_len == 0) {
|
||||
assert(body.len == 0);
|
||||
try stream.writeAll("{}, {}, {");
|
||||
extra_index = extra.end;
|
||||
try stream.writeAll("{}, {}) ");
|
||||
} else {
|
||||
try stream.writeAll("{\n");
|
||||
self.indent += 2;
|
||||
try self.writeBody(stream, body);
|
||||
if (body.len == 0) {
|
||||
try stream.writeAll("{}, {\n");
|
||||
} else {
|
||||
try stream.writeAll("{\n");
|
||||
try self.writeBody(stream, body);
|
||||
|
||||
try stream.writeByteNTimes(' ', self.indent - 2);
|
||||
try stream.writeAll("}, {\n");
|
||||
try stream.writeByteNTimes(' ', self.indent - 2);
|
||||
try stream.writeAll("}, {\n");
|
||||
}
|
||||
|
||||
const bit_bags_count = std.math.divCeil(usize, fields_len, 32) catch unreachable;
|
||||
const body_end = extra.end + body.len;
|
||||
extra_index = body_end + bit_bags_count;
|
||||
const body_end = extra_index;
|
||||
extra_index += bit_bags_count;
|
||||
var bit_bag_index: usize = body_end;
|
||||
var cur_bit_bag: u32 = undefined;
|
||||
var field_i: u32 = 0;
|
||||
@ -3621,14 +3673,22 @@ const Writer = struct {
|
||||
}
|
||||
self.indent -= 2;
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try stream.writeAll("}, {");
|
||||
try stream.writeAll("}) ");
|
||||
}
|
||||
try self.writeSrc(stream, inst_data.src());
|
||||
}
|
||||
|
||||
fn writeOpaqueDecl(self: *Writer, stream: anytype, inst: Inst.Index) !void {
|
||||
const inst_data = self.code.instructions.items(.data)[inst].pl_node;
|
||||
const extra = self.code.extraData(Inst.OpaqueDecl, inst_data.payload_index);
|
||||
const decls_len = extra.data.decls_len;
|
||||
|
||||
if (decls_len == 0) {
|
||||
try stream.writeAll("}) ");
|
||||
} else {
|
||||
try stream.writeAll("\n");
|
||||
self.indent += 2;
|
||||
try self.writeDecls(stream, decls_len, extra_index);
|
||||
_ = try self.writeDecls(stream, decls_len, extra.end);
|
||||
self.indent -= 2;
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try stream.writeAll("}) ");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user