authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-26 12:49:02-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-26 12:49:02-07:00
log646eb1fa934c413f29505f4742c67e61314acd90
tree1da1462d9f3eaf6f0fc330e475c5ad92d265a83d
parent56226449d2106448ac8cd1888a7b302020e22456

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.

2 files changed, 265 insertions(+), 99 deletions(-)

src/AstGen.zig+122-16
......@@ -3254,6 +3254,12 @@ fn structDeclInner(
32543254 .fields_len = @intCast(u32, field_index),
32553255 .decls_len = @intCast(u32, wip_decls.decl_index),
32563256 });
3257 astgen.extra.appendSliceAssumeCapacity(wip_decls.bit_bag.items); // Likely empty.
3258 if (wip_decls.decl_index != 0) {
3259 astgen.extra.appendAssumeCapacity(wip_decls.cur_bit_bag);
3260 }
3261 astgen.extra.appendSliceAssumeCapacity(wip_decls.payload.items);
3262
32573263 astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items);
32583264
32593265 astgen.extra.appendSliceAssumeCapacity(bit_bag.items); // Likely empty.
......@@ -3262,12 +3268,6 @@ fn structDeclInner(
32623268 }
32633269 astgen.extra.appendSliceAssumeCapacity(fields_data.items);
32643270
3265 astgen.extra.appendSliceAssumeCapacity(wip_decls.bit_bag.items); // Likely empty.
3266 if (wip_decls.decl_index != 0) {
3267 astgen.extra.appendAssumeCapacity(wip_decls.cur_bit_bag);
3268 }
3269 astgen.extra.appendSliceAssumeCapacity(wip_decls.payload.items);
3270
32713271 return gz.indexToRef(decl_inst);
32723272}
32733273
......@@ -3479,18 +3479,18 @@ fn unionDeclInner(
34793479 .fields_len = @intCast(u32, field_index),
34803480 .decls_len = @intCast(u32, wip_decls.decl_index),
34813481 });
3482 astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items);
3483
3484 astgen.extra.appendSliceAssumeCapacity(bit_bag.items); // Likely empty.
3485 astgen.extra.appendAssumeCapacity(cur_bit_bag);
3486 astgen.extra.appendSliceAssumeCapacity(fields_data.items);
3487
34883482 astgen.extra.appendSliceAssumeCapacity(wip_decls.bit_bag.items); // Likely empty.
34893483 if (wip_decls.decl_index != 0) {
34903484 astgen.extra.appendAssumeCapacity(wip_decls.cur_bit_bag);
34913485 }
34923486 astgen.extra.appendSliceAssumeCapacity(wip_decls.payload.items);
34933487
3488 astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items);
3489
3490 astgen.extra.appendSliceAssumeCapacity(bit_bag.items); // Likely empty.
3491 astgen.extra.appendAssumeCapacity(cur_bit_bag);
3492 astgen.extra.appendSliceAssumeCapacity(fields_data.items);
3493
34943494 return gz.indexToRef(decl_inst);
34953495}
34963496
......@@ -3811,11 +3811,121 @@ fn containerDecl(
38113811 .fields_len = @intCast(u32, field_index),
38123812 .decls_len = @intCast(u32, wip_decls.decl_index),
38133813 });
3814 astgen.extra.appendSliceAssumeCapacity(wip_decls.bit_bag.items); // Likely empty.
3815 if (wip_decls.decl_index != 0) {
3816 astgen.extra.appendAssumeCapacity(wip_decls.cur_bit_bag);
3817 }
3818 astgen.extra.appendSliceAssumeCapacity(wip_decls.payload.items);
3819
38143820 astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items);
38153821 astgen.extra.appendSliceAssumeCapacity(bit_bag.items); // Likely empty.
38163822 astgen.extra.appendAssumeCapacity(cur_bit_bag);
38173823 astgen.extra.appendSliceAssumeCapacity(fields_data.items);
38183824
3825 return rvalue(gz, scope, rl, gz.indexToRef(decl_inst), node);
3826 },
3827 .keyword_opaque => {
3828 var wip_decls: WipDecls = .{};
3829 defer wip_decls.deinit(gpa);
3830
3831 for (container_decl.ast.members) |member_node| {
3832 const member = switch (node_tags[member_node]) {
3833 .container_field_init => tree.containerFieldInit(member_node),
3834 .container_field_align => tree.containerFieldAlign(member_node),
3835 .container_field => tree.containerField(member_node),
3836
3837 .fn_decl => {
3838 const fn_proto = node_datas[member_node].lhs;
3839 const body = node_datas[member_node].rhs;
3840 switch (node_tags[fn_proto]) {
3841 .fn_proto_simple => {
3842 var params: [1]ast.Node.Index = undefined;
3843 try astgen.fnDecl(gz, &wip_decls, body, tree.fnProtoSimple(&params, fn_proto));
3844 continue;
3845 },
3846 .fn_proto_multi => {
3847 try astgen.fnDecl(gz, &wip_decls, body, tree.fnProtoMulti(fn_proto));
3848 continue;
3849 },
3850 .fn_proto_one => {
3851 var params: [1]ast.Node.Index = undefined;
3852 try astgen.fnDecl(gz, &wip_decls, body, tree.fnProtoOne(&params, fn_proto));
3853 continue;
3854 },
3855 .fn_proto => {
3856 try astgen.fnDecl(gz, &wip_decls, body, tree.fnProto(fn_proto));
3857 continue;
3858 },
3859 else => unreachable,
3860 }
3861 },
3862 .fn_proto_simple => {
3863 var params: [1]ast.Node.Index = undefined;
3864 try astgen.fnDecl(gz, &wip_decls, 0, tree.fnProtoSimple(&params, member_node));
3865 continue;
3866 },
3867 .fn_proto_multi => {
3868 try astgen.fnDecl(gz, &wip_decls, 0, tree.fnProtoMulti(member_node));
3869 continue;
3870 },
3871 .fn_proto_one => {
3872 var params: [1]ast.Node.Index = undefined;
3873 try astgen.fnDecl(gz, &wip_decls, 0, tree.fnProtoOne(&params, member_node));
3874 continue;
3875 },
3876 .fn_proto => {
3877 try astgen.fnDecl(gz, &wip_decls, 0, tree.fnProto(member_node));
3878 continue;
3879 },
3880
3881 .global_var_decl => {
3882 try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.globalVarDecl(member_node));
3883 continue;
3884 },
3885 .local_var_decl => {
3886 try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.localVarDecl(member_node));
3887 continue;
3888 },
3889 .simple_var_decl => {
3890 try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.simpleVarDecl(member_node));
3891 continue;
3892 },
3893 .aligned_var_decl => {
3894 try astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.alignedVarDecl(member_node));
3895 continue;
3896 },
3897
3898 .@"comptime" => {
3899 try astgen.comptimeDecl(gz, scope, member_node);
3900 continue;
3901 },
3902 .@"usingnamespace" => {
3903 try astgen.usingnamespaceDecl(gz, scope, member_node);
3904 continue;
3905 },
3906 .test_decl => {
3907 try astgen.testDecl(gz, scope, member_node);
3908 continue;
3909 },
3910 else => unreachable,
3911 };
3912 }
3913 {
3914 const empty_slot_count = WipDecls.fields_per_u32 - (wip_decls.decl_index % WipDecls.fields_per_u32);
3915 if (empty_slot_count < WipDecls.fields_per_u32) {
3916 wip_decls.cur_bit_bag >>= @intCast(u5, empty_slot_count * WipDecls.bits_per_field);
3917 }
3918 }
3919 const decl_inst = try gz.addBlock(.opaque_decl, node);
3920 try gz.instructions.append(gpa, decl_inst);
3921
3922 try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.OpaqueDecl).Struct.fields.len +
3923 wip_decls.bit_bag.items.len + @boolToInt(wip_decls.decl_index != 0) +
3924 wip_decls.payload.items.len);
3925 const zir_datas = astgen.instructions.items(.data);
3926 zir_datas[decl_inst].pl_node.payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.OpaqueDecl{
3927 .decls_len = @intCast(u32, wip_decls.decl_index),
3928 });
38193929 astgen.extra.appendSliceAssumeCapacity(wip_decls.bit_bag.items); // Likely empty.
38203930 if (wip_decls.decl_index != 0) {
38213931 astgen.extra.appendAssumeCapacity(wip_decls.cur_bit_bag);
......@@ -3824,10 +3934,6 @@ fn containerDecl(
38243934
38253935 return rvalue(gz, scope, rl, gz.indexToRef(decl_inst), node);
38263936 },
3827 .keyword_opaque => {
3828 const result = try gz.addNode(.opaque_decl, node);
3829 return rvalue(gz, scope, rl, result, node);
3830 },
38313937 else => unreachable,
38323938 }
38333939}
src/Zir.zig+143-83
......@@ -312,7 +312,7 @@ pub const Inst = struct {
312312 /// Same as `enum_decl`, except the enum is non-exhaustive.
313313 enum_decl_nonexhaustive,
314314 /// An opaque type definition. Provides an AST node only.
315 /// Uses the `node` union field.
315 /// Uses the `pl_node` union field. Payload is `OpaqueDecl`.
316316 opaque_decl,
317317 /// An error set type definition. Contains a list of field names.
318318 /// Uses the `pl_node` union field. Payload is `ErrorSetDecl`.
......@@ -2368,29 +2368,29 @@ pub const Inst = struct {
23682368 };
23692369
23702370 /// Trailing:
2371 /// 0. inst: Index // for every body_len
2372 /// 1. has_bits: u32 // for every 16 fields
2373 /// - sets of 2 bits:
2374 /// 0b0X: whether corresponding field has an align expression
2375 /// 0bX0: whether corresponding field has a default expression
2376 /// 2. fields: { // for every fields_len
2377 /// field_name: u32,
2378 /// field_type: Ref,
2379 /// align: Ref, // if corresponding bit is set
2380 /// default_value: Ref, // if corresponding bit is set
2381 /// }
2382 /// 3. decl_bits: u32 // for every 8 decls
2371 /// 0. decl_bits: u32 // for every 8 decls
23832372 /// - sets of 4 bits:
23842373 /// 0b000X: whether corresponding decl is pub
23852374 /// 0b00X0: whether corresponding decl is exported
23862375 /// 0b0X00: whether corresponding decl has an align expression
23872376 /// 0bX000: whether corresponding decl has a linksection expression
2388 /// 4. decl: { // for every decls_len
2377 /// 1. decl: { // for every decls_len
23892378 /// name: u32, // null terminated string index
23902379 /// value: Index,
23912380 /// align: Ref, // if corresponding bit is set
23922381 /// link_section: Ref, // if corresponding bit is set
23932382 /// }
2383 /// 2. inst: Index // for every body_len
2384 /// 3. has_bits: u32 // for every 16 fields
2385 /// - sets of 2 bits:
2386 /// 0b0X: whether corresponding field has an align expression
2387 /// 0bX0: whether corresponding field has a default expression
2388 /// 4. fields: { // for every fields_len
2389 /// field_name: u32,
2390 /// field_type: Ref,
2391 /// align: Ref, // if corresponding bit is set
2392 /// default_value: Ref, // if corresponding bit is set
2393 /// }
23942394 pub const StructDecl = struct {
23952395 body_len: u32,
23962396 fields_len: u32,
......@@ -2398,25 +2398,25 @@ pub const Inst = struct {
23982398 };
23992399
24002400 /// Trailing:
2401 /// 0. inst: Index // for every body_len
2402 /// 1. has_bits: u32 // for every 32 fields
2403 /// - the bit is whether corresponding field has an value expression
2404 /// 2. fields: { // for every fields_len
2405 /// field_name: u32,
2406 /// value: Ref, // if corresponding bit is set
2407 /// }
2408 /// 3. decl_bits: u32 // for every 8 decls
2401 /// 0. decl_bits: u32 // for every 8 decls
24092402 /// - sets of 4 bits:
24102403 /// 0b000X: whether corresponding decl is pub
24112404 /// 0b00X0: whether corresponding decl is exported
24122405 /// 0b0X00: whether corresponding decl has an align expression
24132406 /// 0bX000: whether corresponding decl has a linksection expression
2414 /// 4. decl: { // for every decls_len
2407 /// 1. decl: { // for every decls_len
24152408 /// name: u32, // null terminated string index
24162409 /// value: Index,
24172410 /// align: Ref, // if corresponding bit is set
24182411 /// link_section: Ref, // if corresponding bit is set
24192412 /// }
2413 /// 2. inst: Index // for every body_len
2414 /// 3. has_bits: u32 // for every 32 fields
2415 /// - the bit is whether corresponding field has an value expression
2416 /// 4. fields: { // for every fields_len
2417 /// field_name: u32,
2418 /// value: Ref, // if corresponding bit is set
2419 /// }
24202420 pub const EnumDecl = struct {
24212421 /// Can be `Ref.none`.
24222422 tag_type: Ref,
......@@ -2426,8 +2426,20 @@ pub const Inst = struct {
24262426 };
24272427
24282428 /// Trailing:
2429 /// 0. inst: Index // for every body_len
2430 /// 1. has_bits: u32 // for every 8 fields
2429 /// 0. decl_bits: u32 // for every 8 decls
2430 /// - sets of 4 bits:
2431 /// 0b000X: whether corresponding decl is pub
2432 /// 0b00X0: whether corresponding decl is exported
2433 /// 0b0X00: whether corresponding decl has an align expression
2434 /// 0bX000: whether corresponding decl has a linksection expression
2435 /// 1. decl: { // for every decls_len
2436 /// name: u32, // null terminated string index
2437 /// value: Index,
2438 /// align: Ref, // if corresponding bit is set
2439 /// link_section: Ref, // if corresponding bit is set
2440 /// }
2441 /// 2. inst: Index // for every body_len
2442 /// 3. has_bits: u32 // for every 8 fields
24312443 /// - sets of 4 bits:
24322444 /// 0b000X: whether corresponding field has a type expression
24332445 /// 0b00X0: whether corresponding field has a align expression
......@@ -2437,29 +2449,34 @@ pub const Inst = struct {
24372449 /// to indicate whether auto enum tag is enabled.
24382450 /// 0 = union(tag_type)
24392451 /// 1 = union(enum(tag_type))
2440 /// 2. fields: { // for every fields_len
2452 /// 4. fields: { // for every fields_len
24412453 /// field_name: u32, // null terminated string index
24422454 /// field_type: Ref, // if corresponding bit is set
24432455 /// align: Ref, // if corresponding bit is set
24442456 /// tag_value: Ref, // if corresponding bit is set
24452457 /// }
2446 /// 3. decl_bits: u32 // for every 8 decls
2458 pub const UnionDecl = struct {
2459 /// Can be `Ref.none`.
2460 tag_type: Ref,
2461 body_len: u32,
2462 fields_len: u32,
2463 decls_len: u32,
2464 };
2465
2466 /// Trailing:
2467 /// 0. decl_bits: u32 // for every 8 decls
24472468 /// - sets of 4 bits:
24482469 /// 0b000X: whether corresponding decl is pub
24492470 /// 0b00X0: whether corresponding decl is exported
24502471 /// 0b0X00: whether corresponding decl has an align expression
24512472 /// 0bX000: whether corresponding decl has a linksection expression
2452 /// 4. decl: { // for every decls_len
2473 /// 1. decl: { // for every decls_len
24532474 /// name: u32, // null terminated string index
24542475 /// value: Index,
24552476 /// align: Ref, // if corresponding bit is set
24562477 /// link_section: Ref, // if corresponding bit is set
24572478 /// }
2458 pub const UnionDecl = struct {
2459 /// Can be `Ref.none`.
2460 tag_type: Ref,
2461 body_len: u32,
2462 fields_len: u32,
2479 pub const OpaqueDecl = struct {
24632480 decls_len: u32,
24642481 };
24652482
......@@ -2897,6 +2914,8 @@ const Writer = struct {
28972914 .enum_decl_nonexhaustive,
28982915 => try self.writeEnumDecl(stream, inst),
28992916
2917 .opaque_decl => try self.writeOpaqueDecl(stream, inst),
2918
29002919 .switch_block => try self.writePlNodeSwitchBr(stream, inst, .none),
29012920 .switch_block_else => try self.writePlNodeSwitchBr(stream, inst, .@"else"),
29022921 .switch_block_under => try self.writePlNodeSwitchBr(stream, inst, .under),
......@@ -2919,7 +2938,6 @@ const Writer = struct {
29192938
29202939 .breakpoint,
29212940 .fence,
2922 .opaque_decl,
29232941 .dbg_stmt_node,
29242942 .repeat,
29252943 .repeat_inline,
......@@ -3321,27 +3339,45 @@ const Writer = struct {
33213339 fn writeStructDecl(self: *Writer, stream: anytype, inst: Inst.Index) !void {
33223340 const inst_data = self.code.instructions.items(.data)[inst].pl_node;
33233341 const extra = self.code.extraData(Inst.StructDecl, inst_data.payload_index);
3324 const body = self.code.extra[extra.end..][0..extra.data.body_len];
33253342 const fields_len = extra.data.fields_len;
33263343 const decls_len = extra.data.decls_len;
33273344
33283345 var extra_index: usize = undefined;
33293346
3347 if (decls_len == 0) {
3348 try stream.writeAll("}) ");
3349 extra_index = extra.end;
3350 } else {
3351 try stream.writeAll("\n");
3352 self.indent += 2;
3353 extra_index = try self.writeDecls(stream, decls_len, extra.end);
3354 self.indent -= 2;
3355 try stream.writeByteNTimes(' ', self.indent);
3356 try stream.writeAll("}) ");
3357 }
3358
3359 const body = self.code.extra[extra_index..][0..extra.data.body_len];
3360 extra_index += body.len;
3361
33303362 if (fields_len == 0) {
33313363 assert(body.len == 0);
33323364 try stream.writeAll("{}, {}, {");
33333365 extra_index = extra.end;
33343366 } else {
3335 try stream.writeAll("{\n");
33363367 self.indent += 2;
3337 try self.writeBody(stream, body);
3368 if (body.len == 0) {
3369 try stream.writeAll("{}, {\n");
3370 } else {
3371 try stream.writeAll("{\n");
3372 try self.writeBody(stream, body);
33383373
3339 try stream.writeByteNTimes(' ', self.indent - 2);
3340 try stream.writeAll("}, {\n");
3374 try stream.writeByteNTimes(' ', self.indent - 2);
3375 try stream.writeAll("}, {\n");
3376 }
33413377
33423378 const bit_bags_count = std.math.divCeil(usize, fields_len, 16) catch unreachable;
3343 const body_end = extra.end + body.len;
3344 extra_index = body_end + bit_bags_count;
3379 const body_end = extra_index;
3380 extra_index += bit_bags_count;
33453381 var bit_bag_index: usize = body_end;
33463382 var cur_bit_bag: u32 = undefined;
33473383 var field_i: u32 = 0;
......@@ -3386,27 +3422,30 @@ const Writer = struct {
33863422 try stream.writeByteNTimes(' ', self.indent);
33873423 try stream.writeAll("}, {");
33883424 }
3389 if (decls_len == 0) {
3390 try stream.writeAll("}) ");
3391 } else {
3392 try stream.writeAll("\n");
3393 self.indent += 2;
3394 try self.writeDecls(stream, decls_len, extra_index);
3395 self.indent -= 2;
3396 try stream.writeByteNTimes(' ', self.indent);
3397 try stream.writeAll("}) ");
3398 }
33993425 try self.writeSrc(stream, inst_data.src());
34003426 }
34013427
34023428 fn writeUnionDecl(self: *Writer, stream: anytype, inst: Inst.Index) !void {
34033429 const inst_data = self.code.instructions.items(.data)[inst].pl_node;
34043430 const extra = self.code.extraData(Inst.UnionDecl, inst_data.payload_index);
3405 const body = self.code.extra[extra.end..][0..extra.data.body_len];
34063431 const fields_len = extra.data.fields_len;
34073432 const decls_len = extra.data.decls_len;
34083433 const tag_type_ref = extra.data.tag_type;
34093434
3435 var extra_index: usize = undefined;
3436
3437 if (decls_len == 0) {
3438 try stream.writeAll("{}, ");
3439 extra_index = extra.end;
3440 } else {
3441 try stream.writeAll("{\n");
3442 self.indent += 2;
3443 extra_index = try self.writeDecls(stream, decls_len, extra.end);
3444 self.indent -= 2;
3445 try stream.writeByteNTimes(' ', self.indent);
3446 try stream.writeAll("}, ");
3447 }
3448
34103449 assert(fields_len != 0);
34113450 var first_has_auto_enum: ?bool = null;
34123451
......@@ -3415,20 +3454,25 @@ const Writer = struct {
34153454 try stream.writeAll(", ");
34163455 }
34173456
3418 var extra_index: usize = undefined;
3457 const body = self.code.extra[extra_index..][0..extra.data.body_len];
3458 extra_index += body.len;
34193459
3420 try stream.writeAll("{\n");
34213460 self.indent += 2;
3422 try self.writeBody(stream, body);
3461 if (body.len == 0) {
3462 try stream.writeAll("{}, {\n");
3463 } else {
3464 try stream.writeAll("{\n");
3465 try self.writeBody(stream, body);
34233466
3424 try stream.writeByteNTimes(' ', self.indent - 2);
3425 try stream.writeAll("}, {\n");
3467 try stream.writeByteNTimes(' ', self.indent - 2);
3468 try stream.writeAll("}, {\n");
3469 }
34263470
34273471 const bits_per_field = 4;
34283472 const fields_per_u32 = 32 / bits_per_field;
34293473 const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;
3430 const body_end = extra.end + body.len;
3431 extra_index = body_end + bit_bags_count;
3474 const body_end = extra_index;
3475 extra_index += bit_bags_count;
34323476 var bit_bag_index: usize = body_end;
34333477 var cur_bit_bag: u32 = undefined;
34343478 var field_i: u32 = 0;
......@@ -3482,23 +3526,13 @@ const Writer = struct {
34823526
34833527 self.indent -= 2;
34843528 try stream.writeByteNTimes(' ', self.indent);
3485 try stream.writeAll("}, {");
3486 if (decls_len == 0) {
3487 try stream.writeAll("}");
3488 } else {
3489 try stream.writeAll("\n");
3490 self.indent += 2;
3491 try self.writeDecls(stream, decls_len, extra_index);
3492 self.indent -= 2;
3493 try stream.writeByteNTimes(' ', self.indent);
3494 try stream.writeAll("}");
3495 }
3529 try stream.writeAll("}");
34963530 try self.writeFlag(stream, ", autoenum", first_has_auto_enum.?);
34973531 try stream.writeAll(") ");
34983532 try self.writeSrc(stream, inst_data.src());
34993533 }
35003534
3501 fn writeDecls(self: *Writer, stream: anytype, decls_len: u32, extra_start: usize) !void {
3535 fn writeDecls(self: *Writer, stream: anytype, decls_len: u32, extra_start: usize) !usize {
35023536 const parent_decl_node = self.parent_decl_node;
35033537 const bit_bags_count = std.math.divCeil(usize, decls_len, 8) catch unreachable;
35043538 var extra_index = extra_start + bit_bags_count;
......@@ -3561,38 +3595,56 @@ const Writer = struct {
35613595 try self.writeSrc(stream, decl_block_inst_data.src());
35623596 try stream.writeAll("\n");
35633597 }
3598 return extra_index;
35643599 }
35653600
35663601 fn writeEnumDecl(self: *Writer, stream: anytype, inst: Inst.Index) !void {
35673602 const inst_data = self.code.instructions.items(.data)[inst].pl_node;
35683603 const extra = self.code.extraData(Inst.EnumDecl, inst_data.payload_index);
3569 const body = self.code.extra[extra.end..][0..extra.data.body_len];
35703604 const fields_len = extra.data.fields_len;
35713605 const decls_len = extra.data.decls_len;
35723606 const tag_type_ref = extra.data.tag_type;
35733607
3608 var extra_index: usize = undefined;
3609
3610 if (decls_len == 0) {
3611 try stream.writeAll("{}, ");
3612 extra_index = extra.end;
3613 } else {
3614 try stream.writeAll("{\n");
3615 self.indent += 2;
3616 extra_index = try self.writeDecls(stream, decls_len, extra.end);
3617 self.indent -= 2;
3618 try stream.writeByteNTimes(' ', self.indent);
3619 try stream.writeAll("}, ");
3620 }
3621
35743622 if (tag_type_ref != .none) {
35753623 try self.writeInstRef(stream, tag_type_ref);
35763624 try stream.writeAll(", ");
35773625 }
35783626
3579 var extra_index: usize = undefined;
3627 const body = self.code.extra[extra_index..][0..extra.data.body_len];
3628 extra_index += body.len;
35803629
35813630 if (fields_len == 0) {
35823631 assert(body.len == 0);
3583 try stream.writeAll("{}, {}, {");
3584 extra_index = extra.end;
3632 try stream.writeAll("{}, {}) ");
35853633 } else {
3586 try stream.writeAll("{\n");
35873634 self.indent += 2;
3588 try self.writeBody(stream, body);
3635 if (body.len == 0) {
3636 try stream.writeAll("{}, {\n");
3637 } else {
3638 try stream.writeAll("{\n");
3639 try self.writeBody(stream, body);
35893640
3590 try stream.writeByteNTimes(' ', self.indent - 2);
3591 try stream.writeAll("}, {\n");
3641 try stream.writeByteNTimes(' ', self.indent - 2);
3642 try stream.writeAll("}, {\n");
3643 }
35923644
35933645 const bit_bags_count = std.math.divCeil(usize, fields_len, 32) catch unreachable;
3594 const body_end = extra.end + body.len;
3595 extra_index = body_end + bit_bags_count;
3646 const body_end = extra_index;
3647 extra_index += bit_bags_count;
35963648 var bit_bag_index: usize = body_end;
35973649 var cur_bit_bag: u32 = undefined;
35983650 var field_i: u32 = 0;
......@@ -3621,14 +3673,22 @@ const Writer = struct {
36213673 }
36223674 self.indent -= 2;
36233675 try stream.writeByteNTimes(' ', self.indent);
3624 try stream.writeAll("}, {");
3676 try stream.writeAll("}) ");
36253677 }
3678 try self.writeSrc(stream, inst_data.src());
3679 }
3680
3681 fn writeOpaqueDecl(self: *Writer, stream: anytype, inst: Inst.Index) !void {
3682 const inst_data = self.code.instructions.items(.data)[inst].pl_node;
3683 const extra = self.code.extraData(Inst.OpaqueDecl, inst_data.payload_index);
3684 const decls_len = extra.data.decls_len;
3685
36263686 if (decls_len == 0) {
36273687 try stream.writeAll("}) ");
36283688 } else {
36293689 try stream.writeAll("\n");
36303690 self.indent += 2;
3631 try self.writeDecls(stream, decls_len, extra_index);
3691 _ = try self.writeDecls(stream, decls_len, extra.end);
36323692 self.indent -= 2;
36333693 try stream.writeByteNTimes(' ', self.indent);
36343694 try stream.writeAll("}) ");