| ... | ... | @@ -312,7 +312,7 @@ pub const Inst = struct { |
| 312 | 312 | /// Same as `enum_decl`, except the enum is non-exhaustive. |
| 313 | 313 | enum_decl_nonexhaustive, |
| 314 | 314 | /// 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`. |
| 316 | 316 | opaque_decl, |
| 317 | 317 | /// An error set type definition. Contains a list of field names. |
| 318 | 318 | /// Uses the `pl_node` union field. Payload is `ErrorSetDecl`. |
| ... | ... | @@ -2368,29 +2368,29 @@ pub const Inst = struct { |
| 2368 | 2368 | }; |
| 2369 | 2369 | |
| 2370 | 2370 | /// 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 |
| 2383 | 2372 | /// - sets of 4 bits: |
| 2384 | 2373 | /// 0b000X: whether corresponding decl is pub |
| 2385 | 2374 | /// 0b00X0: whether corresponding decl is exported |
| 2386 | 2375 | /// 0b0X00: whether corresponding decl has an align expression |
| 2387 | 2376 | /// 0bX000: whether corresponding decl has a linksection expression |
| 2388 | | /// 4. decl: { // for every decls_len |
| 2377 | /// 1. decl: { // for every decls_len |
| 2389 | 2378 | /// name: u32, // null terminated string index |
| 2390 | 2379 | /// value: Index, |
| 2391 | 2380 | /// align: Ref, // if corresponding bit is set |
| 2392 | 2381 | /// link_section: Ref, // if corresponding bit is set |
| 2393 | 2382 | /// } |
| 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 | /// } |
| 2394 | 2394 | pub const StructDecl = struct { |
| 2395 | 2395 | body_len: u32, |
| 2396 | 2396 | fields_len: u32, |
| ... | ... | @@ -2398,25 +2398,25 @@ pub const Inst = struct { |
| 2398 | 2398 | }; |
| 2399 | 2399 | |
| 2400 | 2400 | /// 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 |
| 2409 | 2402 | /// - sets of 4 bits: |
| 2410 | 2403 | /// 0b000X: whether corresponding decl is pub |
| 2411 | 2404 | /// 0b00X0: whether corresponding decl is exported |
| 2412 | 2405 | /// 0b0X00: whether corresponding decl has an align expression |
| 2413 | 2406 | /// 0bX000: whether corresponding decl has a linksection expression |
| 2414 | | /// 4. decl: { // for every decls_len |
| 2407 | /// 1. decl: { // for every decls_len |
| 2415 | 2408 | /// name: u32, // null terminated string index |
| 2416 | 2409 | /// value: Index, |
| 2417 | 2410 | /// align: Ref, // if corresponding bit is set |
| 2418 | 2411 | /// link_section: Ref, // if corresponding bit is set |
| 2419 | 2412 | /// } |
| 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 | /// } |
| 2420 | 2420 | pub const EnumDecl = struct { |
| 2421 | 2421 | /// Can be `Ref.none`. |
| 2422 | 2422 | tag_type: Ref, |
| ... | ... | @@ -2426,8 +2426,20 @@ pub const Inst = struct { |
| 2426 | 2426 | }; |
| 2427 | 2427 | |
| 2428 | 2428 | /// 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 |
| 2431 | 2443 | /// - sets of 4 bits: |
| 2432 | 2444 | /// 0b000X: whether corresponding field has a type expression |
| 2433 | 2445 | /// 0b00X0: whether corresponding field has a align expression |
| ... | ... | @@ -2437,29 +2449,34 @@ pub const Inst = struct { |
| 2437 | 2449 | /// to indicate whether auto enum tag is enabled. |
| 2438 | 2450 | /// 0 = union(tag_type) |
| 2439 | 2451 | /// 1 = union(enum(tag_type)) |
| 2440 | | /// 2. fields: { // for every fields_len |
| 2452 | /// 4. fields: { // for every fields_len |
| 2441 | 2453 | /// field_name: u32, // null terminated string index |
| 2442 | 2454 | /// field_type: Ref, // if corresponding bit is set |
| 2443 | 2455 | /// align: Ref, // if corresponding bit is set |
| 2444 | 2456 | /// tag_value: Ref, // if corresponding bit is set |
| 2445 | 2457 | /// } |
| 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 |
| 2447 | 2468 | /// - sets of 4 bits: |
| 2448 | 2469 | /// 0b000X: whether corresponding decl is pub |
| 2449 | 2470 | /// 0b00X0: whether corresponding decl is exported |
| 2450 | 2471 | /// 0b0X00: whether corresponding decl has an align expression |
| 2451 | 2472 | /// 0bX000: whether corresponding decl has a linksection expression |
| 2452 | | /// 4. decl: { // for every decls_len |
| 2473 | /// 1. decl: { // for every decls_len |
| 2453 | 2474 | /// name: u32, // null terminated string index |
| 2454 | 2475 | /// value: Index, |
| 2455 | 2476 | /// align: Ref, // if corresponding bit is set |
| 2456 | 2477 | /// link_section: Ref, // if corresponding bit is set |
| 2457 | 2478 | /// } |
| 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 { |
| 2463 | 2480 | decls_len: u32, |
| 2464 | 2481 | }; |
| 2465 | 2482 | |
| ... | ... | @@ -2897,6 +2914,8 @@ const Writer = struct { |
| 2897 | 2914 | .enum_decl_nonexhaustive, |
| 2898 | 2915 | => try self.writeEnumDecl(stream, inst), |
| 2899 | 2916 | |
| 2917 | .opaque_decl => try self.writeOpaqueDecl(stream, inst), |
| 2918 | |
| 2900 | 2919 | .switch_block => try self.writePlNodeSwitchBr(stream, inst, .none), |
| 2901 | 2920 | .switch_block_else => try self.writePlNodeSwitchBr(stream, inst, .@"else"), |
| 2902 | 2921 | .switch_block_under => try self.writePlNodeSwitchBr(stream, inst, .under), |
| ... | ... | @@ -2919,7 +2938,6 @@ const Writer = struct { |
| 2919 | 2938 | |
| 2920 | 2939 | .breakpoint, |
| 2921 | 2940 | .fence, |
| 2922 | | .opaque_decl, |
| 2923 | 2941 | .dbg_stmt_node, |
| 2924 | 2942 | .repeat, |
| 2925 | 2943 | .repeat_inline, |
| ... | ... | @@ -3321,27 +3339,45 @@ const Writer = struct { |
| 3321 | 3339 | fn writeStructDecl(self: *Writer, stream: anytype, inst: Inst.Index) !void { |
| 3322 | 3340 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; |
| 3323 | 3341 | const extra = self.code.extraData(Inst.StructDecl, inst_data.payload_index); |
| 3324 | | const body = self.code.extra[extra.end..][0..extra.data.body_len]; |
| 3325 | 3342 | const fields_len = extra.data.fields_len; |
| 3326 | 3343 | const decls_len = extra.data.decls_len; |
| 3327 | 3344 | |
| 3328 | 3345 | var extra_index: usize = undefined; |
| 3329 | 3346 | |
| 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 | |
| 3330 | 3362 | if (fields_len == 0) { |
| 3331 | 3363 | assert(body.len == 0); |
| 3332 | 3364 | try stream.writeAll("{}, {}, {"); |
| 3333 | 3365 | extra_index = extra.end; |
| 3334 | 3366 | } else { |
| 3335 | | try stream.writeAll("{\n"); |
| 3336 | 3367 | 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); |
| 3338 | 3373 | |
| 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 | } |
| 3341 | 3377 | |
| 3342 | 3378 | 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; |
| 3345 | 3381 | var bit_bag_index: usize = body_end; |
| 3346 | 3382 | var cur_bit_bag: u32 = undefined; |
| 3347 | 3383 | var field_i: u32 = 0; |
| ... | ... | @@ -3386,27 +3422,30 @@ const Writer = struct { |
| 3386 | 3422 | try stream.writeByteNTimes(' ', self.indent); |
| 3387 | 3423 | try stream.writeAll("}, {"); |
| 3388 | 3424 | } |
| 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 | | } |
| 3399 | 3425 | try self.writeSrc(stream, inst_data.src()); |
| 3400 | 3426 | } |
| 3401 | 3427 | |
| 3402 | 3428 | fn writeUnionDecl(self: *Writer, stream: anytype, inst: Inst.Index) !void { |
| 3403 | 3429 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; |
| 3404 | 3430 | const extra = self.code.extraData(Inst.UnionDecl, inst_data.payload_index); |
| 3405 | | const body = self.code.extra[extra.end..][0..extra.data.body_len]; |
| 3406 | 3431 | const fields_len = extra.data.fields_len; |
| 3407 | 3432 | const decls_len = extra.data.decls_len; |
| 3408 | 3433 | const tag_type_ref = extra.data.tag_type; |
| 3409 | 3434 | |
| 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 | |
| 3410 | 3449 | assert(fields_len != 0); |
| 3411 | 3450 | var first_has_auto_enum: ?bool = null; |
| 3412 | 3451 | |
| ... | ... | @@ -3415,20 +3454,25 @@ const Writer = struct { |
| 3415 | 3454 | try stream.writeAll(", "); |
| 3416 | 3455 | } |
| 3417 | 3456 | |
| 3418 | | var extra_index: usize = undefined; |
| 3457 | const body = self.code.extra[extra_index..][0..extra.data.body_len]; |
| 3458 | extra_index += body.len; |
| 3419 | 3459 | |
| 3420 | | try stream.writeAll("{\n"); |
| 3421 | 3460 | 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); |
| 3423 | 3466 | |
| 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 | } |
| 3426 | 3470 | |
| 3427 | 3471 | const bits_per_field = 4; |
| 3428 | 3472 | const fields_per_u32 = 32 / bits_per_field; |
| 3429 | 3473 | 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; |
| 3432 | 3476 | var bit_bag_index: usize = body_end; |
| 3433 | 3477 | var cur_bit_bag: u32 = undefined; |
| 3434 | 3478 | var field_i: u32 = 0; |
| ... | ... | @@ -3482,23 +3526,13 @@ const Writer = struct { |
| 3482 | 3526 | |
| 3483 | 3527 | self.indent -= 2; |
| 3484 | 3528 | 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("}"); |
| 3496 | 3530 | try self.writeFlag(stream, ", autoenum", first_has_auto_enum.?); |
| 3497 | 3531 | try stream.writeAll(") "); |
| 3498 | 3532 | try self.writeSrc(stream, inst_data.src()); |
| 3499 | 3533 | } |
| 3500 | 3534 | |
| 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 { |
| 3502 | 3536 | const parent_decl_node = self.parent_decl_node; |
| 3503 | 3537 | const bit_bags_count = std.math.divCeil(usize, decls_len, 8) catch unreachable; |
| 3504 | 3538 | var extra_index = extra_start + bit_bags_count; |
| ... | ... | @@ -3561,38 +3595,56 @@ const Writer = struct { |
| 3561 | 3595 | try self.writeSrc(stream, decl_block_inst_data.src()); |
| 3562 | 3596 | try stream.writeAll("\n"); |
| 3563 | 3597 | } |
| 3598 | return extra_index; |
| 3564 | 3599 | } |
| 3565 | 3600 | |
| 3566 | 3601 | fn writeEnumDecl(self: *Writer, stream: anytype, inst: Inst.Index) !void { |
| 3567 | 3602 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; |
| 3568 | 3603 | const extra = self.code.extraData(Inst.EnumDecl, inst_data.payload_index); |
| 3569 | | const body = self.code.extra[extra.end..][0..extra.data.body_len]; |
| 3570 | 3604 | const fields_len = extra.data.fields_len; |
| 3571 | 3605 | const decls_len = extra.data.decls_len; |
| 3572 | 3606 | const tag_type_ref = extra.data.tag_type; |
| 3573 | 3607 | |
| 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 | |
| 3574 | 3622 | if (tag_type_ref != .none) { |
| 3575 | 3623 | try self.writeInstRef(stream, tag_type_ref); |
| 3576 | 3624 | try stream.writeAll(", "); |
| 3577 | 3625 | } |
| 3578 | 3626 | |
| 3579 | | var extra_index: usize = undefined; |
| 3627 | const body = self.code.extra[extra_index..][0..extra.data.body_len]; |
| 3628 | extra_index += body.len; |
| 3580 | 3629 | |
| 3581 | 3630 | if (fields_len == 0) { |
| 3582 | 3631 | assert(body.len == 0); |
| 3583 | | try stream.writeAll("{}, {}, {"); |
| 3584 | | extra_index = extra.end; |
| 3632 | try stream.writeAll("{}, {}) "); |
| 3585 | 3633 | } else { |
| 3586 | | try stream.writeAll("{\n"); |
| 3587 | 3634 | 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); |
| 3589 | 3640 | |
| 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 | } |
| 3592 | 3644 | |
| 3593 | 3645 | 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; |
| 3596 | 3648 | var bit_bag_index: usize = body_end; |
| 3597 | 3649 | var cur_bit_bag: u32 = undefined; |
| 3598 | 3650 | var field_i: u32 = 0; |
| ... | ... | @@ -3621,14 +3673,22 @@ const Writer = struct { |
| 3621 | 3673 | } |
| 3622 | 3674 | self.indent -= 2; |
| 3623 | 3675 | try stream.writeByteNTimes(' ', self.indent); |
| 3624 | | try stream.writeAll("}, {"); |
| 3676 | try stream.writeAll("}) "); |
| 3625 | 3677 | } |
| 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 | |
| 3626 | 3686 | if (decls_len == 0) { |
| 3627 | 3687 | try stream.writeAll("}) "); |
| 3628 | 3688 | } else { |
| 3629 | 3689 | try stream.writeAll("\n"); |
| 3630 | 3690 | self.indent += 2; |
| 3631 | | try self.writeDecls(stream, decls_len, extra_index); |
| 3691 | _ = try self.writeDecls(stream, decls_len, extra.end); |
| 3632 | 3692 | self.indent -= 2; |
| 3633 | 3693 | try stream.writeByteNTimes(' ', self.indent); |
| 3634 | 3694 | try stream.writeAll("}) "); |