authorgravatar for matthew.h.borkowski@gmail.comMatthew Borkowski <matthew.h.borkowski@gmail.com> 2021-11-01 01:42:02-04:00
committergravatar for matthew.h.borkowski@gmail.comMatthew Borkowski <matthew.h.borkowski@gmail.com> 2021-11-01 05:41:37-04:00
loge712f87a662e9f2711698bc5a74644a5b3b890f3
treeec2408c3c71dc3c87dda625e82a58227634c5257
parentf0260555d6164642569af9e09f57458a938d5de1

astgen.zig: replace WipDecls with WipMembers, use one allocation to collect container decls, fields, and bits, instead of up to four


1 files changed, 273 insertions(+), 348 deletions(-)

src/AstGen.zig+273-348
......@@ -2995,38 +2995,112 @@ fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.I
29952995 return rvalue(gz, rl, result, node);
29962996}
29972997
2998const WipDecls = struct {
2999 decl_index: usize = 0,
3000 cur_bit_bag: u32 = 0,
3001 bit_bag: ArrayListUnmanaged(u32) = .{},
3002 payload: ArrayListUnmanaged(u32) = .{},
2998const WipMembers = struct {
2999 payload: []u32,
3000 decls_start: u32,
3001 field_bits_start: u32,
3002 fields_start: u32,
3003 decls_end: u32,
3004 fields_end: u32,
3005 decl_index: u32 = 0,
3006 field_index: u32 = 0,
3007
3008 const Self = @This();
3009 /// struct, union, enum, and opaque decls all use same 4 bits per decl
3010 const bits_per_decl = 4;
3011 const decls_per_u32 = 32 / bits_per_decl;
3012 /// struct, union, enum, and opaque decls all have maximum size of 10 u32 slots
3013 /// (4 for src_hash + line + name + value + align + link_section + address_space)
3014 const max_decl_size = 10;
3015
3016 pub fn init(gpa: *Allocator, decl_count: u32, field_count: u32, comptime bits_per_field: u32, comptime max_field_size: u32) Allocator.Error!Self {
3017 const decls_start = (decl_count + decls_per_u32 - 1) / decls_per_u32;
3018 const field_bits_start = decls_start + decl_count * max_decl_size;
3019 const fields_start = if (bits_per_field > 0) blk: {
3020 const fields_per_u32 = 32 / bits_per_field;
3021 break :blk field_bits_start + (field_count + fields_per_u32 - 1) / fields_per_u32;
3022 } else field_bits_start;
3023 const capacity = fields_start + field_count * max_field_size;
3024 return Self{
3025 .payload = try gpa.alloc(u32, capacity),
3026 .decls_start = decls_start,
3027 .field_bits_start = field_bits_start,
3028 .fields_start = fields_start,
3029 .decls_end = decls_start,
3030 .fields_end = fields_start,
3031 };
3032 }
30033033
3004 const bits_per_field = 4;
3005 const fields_per_u32 = 32 / bits_per_field;
3006
3007 fn next(
3008 wip_decls: *WipDecls,
3009 gpa: *Allocator,
3010 is_pub: bool,
3011 is_export: bool,
3012 has_align: bool,
3013 has_section_or_addrspace: bool,
3014 ) Allocator.Error!void {
3015 if (wip_decls.decl_index % fields_per_u32 == 0 and wip_decls.decl_index != 0) {
3016 try wip_decls.bit_bag.append(gpa, wip_decls.cur_bit_bag);
3017 wip_decls.cur_bit_bag = 0;
3018 }
3019 wip_decls.cur_bit_bag = (wip_decls.cur_bit_bag >> bits_per_field) |
3034 pub fn nextDecl(self: *Self, is_pub: bool, is_export: bool, has_align: bool, has_section_or_addrspace: bool) void {
3035 const index = self.decl_index / decls_per_u32;
3036 assert(index < self.decls_start);
3037 const bit_bag: u32 = if (self.decl_index % decls_per_u32 == 0) 0 else self.payload[index];
3038 self.payload[index] = (bit_bag >> bits_per_decl) |
30203039 (@as(u32, @boolToInt(is_pub)) << 28) |
30213040 (@as(u32, @boolToInt(is_export)) << 29) |
30223041 (@as(u32, @boolToInt(has_align)) << 30) |
30233042 (@as(u32, @boolToInt(has_section_or_addrspace)) << 31);
3024 wip_decls.decl_index += 1;
3043 self.decl_index += 1;
3044 }
3045
3046 pub fn nextField(self: *Self, comptime bits_per_field: u32, bits: [bits_per_field]bool) void {
3047 const fields_per_u32 = 32 / bits_per_field;
3048 const index = self.field_bits_start + self.field_index / fields_per_u32;
3049 assert(index < self.fields_start);
3050 var bit_bag: u32 = if (self.field_index % fields_per_u32 == 0) 0 else self.payload[index];
3051 bit_bag >>= bits_per_field;
3052 comptime var i = 0;
3053 inline while (i < bits_per_field) : (i += 1) {
3054 bit_bag |= @as(u32, @boolToInt(bits[i])) << (32 - bits_per_field + i);
3055 }
3056 self.payload[index] = bit_bag;
3057 self.field_index += 1;
3058 }
3059
3060 pub fn appendToDecl(self: *Self, data: u32) void {
3061 assert(self.decls_end < self.field_bits_start);
3062 self.payload[self.decls_end] = data;
3063 self.decls_end += 1;
3064 }
3065
3066 pub fn appendToDeclSlice(self: *Self, data: []const u32) void {
3067 assert(self.decls_end + data.len <= self.field_bits_start);
3068 mem.copy(u32, self.payload[self.decls_end..], data);
3069 self.decls_end += @intCast(u32, data.len);
3070 }
3071
3072 pub fn appendToField(self: *Self, data: u32) void {
3073 assert(self.fields_end < self.payload.len);
3074 self.payload[self.fields_end] = data;
3075 self.fields_end += 1;
30253076 }
30263077
3027 fn deinit(wip_decls: *WipDecls, gpa: *Allocator) void {
3028 wip_decls.bit_bag.deinit(gpa);
3029 wip_decls.payload.deinit(gpa);
3078 pub fn finishBits(self: *Self, comptime bits_per_field: u32) void {
3079 const empty_decl_slots = decls_per_u32 - (self.decl_index % decls_per_u32);
3080 if (self.decl_index > 0 and empty_decl_slots < decls_per_u32) {
3081 const index = self.decl_index / decls_per_u32;
3082 self.payload[index] >>= @intCast(u5, empty_decl_slots * bits_per_decl);
3083 }
3084 if (bits_per_field > 0) {
3085 const fields_per_u32 = 32 / bits_per_field;
3086 const empty_field_slots = fields_per_u32 - (self.field_index % fields_per_u32);
3087 if (self.field_index > 0 and empty_field_slots < fields_per_u32) {
3088 const index = self.field_bits_start + self.field_index / fields_per_u32;
3089 self.payload[index] >>= @intCast(u5, empty_field_slots * bits_per_field);
3090 }
3091 }
3092 }
3093
3094 pub fn declsSlice(self: *Self) []u32 {
3095 return self.payload[0..self.decls_end];
3096 }
3097
3098 pub fn fieldsSlice(self: *Self) []u32 {
3099 return self.payload[self.field_bits_start..self.fields_end];
3100 }
3101
3102 pub fn deinit(self: *Self, gpa: *Allocator) void {
3103 gpa.free(self.payload);
30303104 }
30313105};
30323106
......@@ -3034,7 +3108,7 @@ fn fnDecl(
30343108 astgen: *AstGen,
30353109 gz: *GenZir,
30363110 scope: *Scope,
3037 wip_decls: *WipDecls,
3111 wip_members: *WipMembers,
30383112 decl_node: Ast.Node.Index,
30393113 body_node: Ast.Node.Index,
30403114 fn_proto: Ast.full.FnProto,
......@@ -3086,7 +3160,7 @@ fn fnDecl(
30863160 break :blk token_tags[maybe_inline_token] == .keyword_inline;
30873161 };
30883162 const has_section_or_addrspace = fn_proto.ast.section_expr != 0 or fn_proto.ast.addrspace_expr != 0;
3089 try wip_decls.next(gpa, is_pub, is_export, fn_proto.ast.align_expr != 0, has_section_or_addrspace);
3163 wip_members.nextDecl(is_pub, is_export, fn_proto.ast.align_expr != 0, has_section_or_addrspace);
30903164
30913165 var params_scope = &fn_gz.base;
30923166 const is_var_args = is_var_args: {
......@@ -3287,25 +3361,23 @@ fn fnDecl(
32873361 _ = try decl_gz.addBreak(.break_inline, block_inst, func_inst);
32883362 try decl_gz.setBlockBody(block_inst);
32893363
3290 try wip_decls.payload.ensureUnusedCapacity(gpa, 10);
32913364 {
32923365 const contents_hash = std.zig.hashSrc(tree.getNodeSource(decl_node));
32933366 const casted = @bitCast([4]u32, contents_hash);
3294 wip_decls.payload.appendSliceAssumeCapacity(&casted);
3367 wip_members.appendToDeclSlice(&casted);
32953368 }
32963369 {
32973370 const line_delta = decl_gz.decl_line - gz.decl_line;
3298 wip_decls.payload.appendAssumeCapacity(line_delta);
3371 wip_members.appendToDecl(line_delta);
32993372 }
3300 wip_decls.payload.appendAssumeCapacity(fn_name_str_index);
3301 wip_decls.payload.appendAssumeCapacity(block_inst);
3373 wip_members.appendToDecl(fn_name_str_index);
3374 wip_members.appendToDecl(block_inst);
33023375 if (align_inst != .none) {
3303 wip_decls.payload.appendAssumeCapacity(@enumToInt(align_inst));
3376 wip_members.appendToDecl(@enumToInt(align_inst));
33043377 }
3305
33063378 if (has_section_or_addrspace) {
3307 wip_decls.payload.appendAssumeCapacity(@enumToInt(section_inst));
3308 wip_decls.payload.appendAssumeCapacity(@enumToInt(addrspace_inst));
3379 wip_members.appendToDecl(@enumToInt(section_inst));
3380 wip_members.appendToDecl(@enumToInt(addrspace_inst));
33093381 }
33103382}
33113383
......@@ -3313,7 +3385,7 @@ fn globalVarDecl(
33133385 astgen: *AstGen,
33143386 gz: *GenZir,
33153387 scope: *Scope,
3316 wip_decls: *WipDecls,
3388 wip_members: *WipMembers,
33173389 node: Ast.Node.Index,
33183390 var_decl: Ast.full.VarDecl,
33193391) InnerError!void {
......@@ -3359,7 +3431,7 @@ fn globalVarDecl(
33593431 break :inst try comptimeExpr(&block_scope, &block_scope.base, .{ .ty = .const_slice_u8_type }, var_decl.ast.section_node);
33603432 };
33613433 const has_section_or_addrspace = section_inst != .none or addrspace_inst != .none;
3362 try wip_decls.next(gpa, is_pub, is_export, align_inst != .none, has_section_or_addrspace);
3434 wip_members.nextDecl(is_pub, is_export, align_inst != .none, has_section_or_addrspace);
33633435
33643436 const is_threadlocal = if (var_decl.threadlocal_token) |tok| blk: {
33653437 if (!is_mutable) {
......@@ -3437,24 +3509,23 @@ fn globalVarDecl(
34373509 _ = try block_scope.addBreak(.break_inline, block_inst, var_inst);
34383510 try block_scope.setBlockBody(block_inst);
34393511
3440 try wip_decls.payload.ensureUnusedCapacity(gpa, 10);
34413512 {
34423513 const contents_hash = std.zig.hashSrc(tree.getNodeSource(node));
34433514 const casted = @bitCast([4]u32, contents_hash);
3444 wip_decls.payload.appendSliceAssumeCapacity(&casted);
3515 wip_members.appendToDeclSlice(&casted);
34453516 }
34463517 {
34473518 const line_delta = block_scope.decl_line - gz.decl_line;
3448 wip_decls.payload.appendAssumeCapacity(line_delta);
3519 wip_members.appendToDecl(line_delta);
34493520 }
3450 wip_decls.payload.appendAssumeCapacity(name_str_index);
3451 wip_decls.payload.appendAssumeCapacity(block_inst);
3521 wip_members.appendToDecl(name_str_index);
3522 wip_members.appendToDecl(block_inst);
34523523 if (align_inst != .none) {
3453 wip_decls.payload.appendAssumeCapacity(@enumToInt(align_inst));
3524 wip_members.appendToDecl(@enumToInt(align_inst));
34543525 }
34553526 if (has_section_or_addrspace) {
3456 wip_decls.payload.appendAssumeCapacity(@enumToInt(section_inst));
3457 wip_decls.payload.appendAssumeCapacity(@enumToInt(addrspace_inst));
3527 wip_members.appendToDecl(@enumToInt(section_inst));
3528 wip_members.appendToDecl(@enumToInt(addrspace_inst));
34583529 }
34593530}
34603531
......@@ -3462,7 +3533,7 @@ fn comptimeDecl(
34623533 astgen: *AstGen,
34633534 gz: *GenZir,
34643535 scope: *Scope,
3465 wip_decls: *WipDecls,
3536 wip_members: *WipMembers,
34663537 node: Ast.Node.Index,
34673538) InnerError!void {
34683539 const gpa = astgen.gpa;
......@@ -3473,7 +3544,7 @@ fn comptimeDecl(
34733544 // Up top so the ZIR instruction index marks the start range of this
34743545 // top-level declaration.
34753546 const block_inst = try gz.addBlock(.block_inline, node);
3476 try wip_decls.next(gpa, false, false, false, false);
3547 wip_members.nextDecl(false, false, false, false);
34773548
34783549 var decl_block: GenZir = .{
34793550 .force_comptime = true,
......@@ -3491,25 +3562,24 @@ fn comptimeDecl(
34913562 }
34923563 try decl_block.setBlockBody(block_inst);
34933564
3494 try wip_decls.payload.ensureUnusedCapacity(gpa, 7);
34953565 {
34963566 const contents_hash = std.zig.hashSrc(tree.getNodeSource(node));
34973567 const casted = @bitCast([4]u32, contents_hash);
3498 wip_decls.payload.appendSliceAssumeCapacity(&casted);
3568 wip_members.appendToDeclSlice(&casted);
34993569 }
35003570 {
35013571 const line_delta = decl_block.decl_line - gz.decl_line;
3502 wip_decls.payload.appendAssumeCapacity(line_delta);
3572 wip_members.appendToDecl(line_delta);
35033573 }
3504 wip_decls.payload.appendAssumeCapacity(0);
3505 wip_decls.payload.appendAssumeCapacity(block_inst);
3574 wip_members.appendToDecl(0);
3575 wip_members.appendToDecl(block_inst);
35063576}
35073577
35083578fn usingnamespaceDecl(
35093579 astgen: *AstGen,
35103580 gz: *GenZir,
35113581 scope: *Scope,
3512 wip_decls: *WipDecls,
3582 wip_members: *WipMembers,
35133583 node: Ast.Node.Index,
35143584) InnerError!void {
35153585 const gpa = astgen.gpa;
......@@ -3526,7 +3596,7 @@ fn usingnamespaceDecl(
35263596 // Up top so the ZIR instruction index marks the start range of this
35273597 // top-level declaration.
35283598 const block_inst = try gz.addBlock(.block_inline, node);
3529 try wip_decls.next(gpa, is_pub, true, false, false);
3599 wip_members.nextDecl(is_pub, true, false, false);
35303600
35313601 var decl_block: GenZir = .{
35323602 .force_comptime = true,
......@@ -3542,25 +3612,24 @@ fn usingnamespaceDecl(
35423612 _ = try decl_block.addBreak(.break_inline, block_inst, namespace_inst);
35433613 try decl_block.setBlockBody(block_inst);
35443614
3545 try wip_decls.payload.ensureUnusedCapacity(gpa, 7);
35463615 {
35473616 const contents_hash = std.zig.hashSrc(tree.getNodeSource(node));
35483617 const casted = @bitCast([4]u32, contents_hash);
3549 wip_decls.payload.appendSliceAssumeCapacity(&casted);
3618 wip_members.appendToDeclSlice(&casted);
35503619 }
35513620 {
35523621 const line_delta = decl_block.decl_line - gz.decl_line;
3553 wip_decls.payload.appendAssumeCapacity(line_delta);
3622 wip_members.appendToDecl(line_delta);
35543623 }
3555 wip_decls.payload.appendAssumeCapacity(0);
3556 wip_decls.payload.appendAssumeCapacity(block_inst);
3624 wip_members.appendToDecl(0);
3625 wip_members.appendToDecl(block_inst);
35573626}
35583627
35593628fn testDecl(
35603629 astgen: *AstGen,
35613630 gz: *GenZir,
35623631 scope: *Scope,
3563 wip_decls: *WipDecls,
3632 wip_members: *WipMembers,
35643633 node: Ast.Node.Index,
35653634) InnerError!void {
35663635 const gpa = astgen.gpa;
......@@ -3572,7 +3641,7 @@ fn testDecl(
35723641 // top-level declaration.
35733642 const block_inst = try gz.addBlock(.block_inline, node);
35743643
3575 try wip_decls.next(gpa, false, false, false, false);
3644 wip_members.nextDecl(false, false, false, false);
35763645
35773646 var decl_block: GenZir = .{
35783647 .force_comptime = true,
......@@ -3643,18 +3712,17 @@ fn testDecl(
36433712 _ = try decl_block.addBreak(.break_inline, block_inst, func_inst);
36443713 try decl_block.setBlockBody(block_inst);
36453714
3646 try wip_decls.payload.ensureUnusedCapacity(gpa, 7);
36473715 {
36483716 const contents_hash = std.zig.hashSrc(tree.getNodeSource(node));
36493717 const casted = @bitCast([4]u32, contents_hash);
3650 wip_decls.payload.appendSliceAssumeCapacity(&casted);
3718 wip_members.appendToDeclSlice(&casted);
36513719 }
36523720 {
36533721 const line_delta = decl_block.decl_line - gz.decl_line;
3654 wip_decls.payload.appendAssumeCapacity(line_delta);
3722 wip_members.appendToDecl(line_delta);
36553723 }
3656 wip_decls.payload.appendAssumeCapacity(test_name);
3657 wip_decls.payload.appendAssumeCapacity(block_inst);
3724 wip_members.appendToDecl(test_name);
3725 wip_members.appendToDecl(block_inst);
36583726}
36593727
36603728fn structDeclInner(
......@@ -3705,25 +3773,15 @@ fn structDeclInner(
37053773 };
37063774 defer block_scope.instructions.deinit(gpa);
37073775
3708 try astgen.scanDecls(&namespace, container_decl.ast.members);
3709
3710 var wip_decls: WipDecls = .{};
3711 defer wip_decls.deinit(gpa);
3712
3713 // We don't know which members are fields until we iterate, so cannot do
3714 // an accurate ensureTotalCapacity yet.
3715 var fields_data = ArrayListUnmanaged(u32){};
3716 defer fields_data.deinit(gpa);
3776 const decl_count = try astgen.scanDecls(&namespace, container_decl.ast.members);
3777 const field_count = @intCast(u32, container_decl.ast.members.len - decl_count);
37173778
37183779 const bits_per_field = 4;
3719 const fields_per_u32 = 32 / bits_per_field;
3720 // We only need this if there are greater than fields_per_u32 fields.
3721 var bit_bag = ArrayListUnmanaged(u32){};
3722 defer bit_bag.deinit(gpa);
3780 const max_field_size = 4;
3781 var wip_members = try WipMembers.init(gpa, decl_count, field_count, bits_per_field, max_field_size);
3782 defer wip_members.deinit(gpa);
37233783
37243784 var known_has_bits = false;
3725 var cur_bit_bag: u32 = 0;
3726 var field_index: usize = 0;
37273785 for (container_decl.ast.members) |member_node| {
37283786 const member = switch (node_tags[member_node]) {
37293787 .container_field_init => tree.containerFieldInit(member_node),
......@@ -3736,14 +3794,14 @@ fn structDeclInner(
37363794 switch (node_tags[fn_proto]) {
37373795 .fn_proto_simple => {
37383796 var params: [1]Ast.Node.Index = undefined;
3739 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
3797 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
37403798 error.OutOfMemory => return error.OutOfMemory,
37413799 error.AnalysisFail => {},
37423800 };
37433801 continue;
37443802 },
37453803 .fn_proto_multi => {
3746 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
3804 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
37473805 error.OutOfMemory => return error.OutOfMemory,
37483806 error.AnalysisFail => {},
37493807 };
......@@ -3751,14 +3809,14 @@ fn structDeclInner(
37513809 },
37523810 .fn_proto_one => {
37533811 var params: [1]Ast.Node.Index = undefined;
3754 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
3812 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
37553813 error.OutOfMemory => return error.OutOfMemory,
37563814 error.AnalysisFail => {},
37573815 };
37583816 continue;
37593817 },
37603818 .fn_proto => {
3761 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
3819 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
37623820 error.OutOfMemory => return error.OutOfMemory,
37633821 error.AnalysisFail => {},
37643822 };
......@@ -3769,14 +3827,14 @@ fn structDeclInner(
37693827 },
37703828 .fn_proto_simple => {
37713829 var params: [1]Ast.Node.Index = undefined;
3772 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
3830 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
37733831 error.OutOfMemory => return error.OutOfMemory,
37743832 error.AnalysisFail => {},
37753833 };
37763834 continue;
37773835 },
37783836 .fn_proto_multi => {
3779 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
3837 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
37803838 error.OutOfMemory => return error.OutOfMemory,
37813839 error.AnalysisFail => {},
37823840 };
......@@ -3784,14 +3842,14 @@ fn structDeclInner(
37843842 },
37853843 .fn_proto_one => {
37863844 var params: [1]Ast.Node.Index = undefined;
3787 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
3845 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
37883846 error.OutOfMemory => return error.OutOfMemory,
37893847 error.AnalysisFail => {},
37903848 };
37913849 continue;
37923850 },
37933851 .fn_proto => {
3794 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
3852 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
37953853 error.OutOfMemory => return error.OutOfMemory,
37963854 error.AnalysisFail => {},
37973855 };
......@@ -3799,28 +3857,28 @@ fn structDeclInner(
37993857 },
38003858
38013859 .global_var_decl => {
3802 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
3860 astgen.globalVarDecl(gz, &namespace.base, &wip_members, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
38033861 error.OutOfMemory => return error.OutOfMemory,
38043862 error.AnalysisFail => {},
38053863 };
38063864 continue;
38073865 },
38083866 .local_var_decl => {
3809 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
3867 astgen.globalVarDecl(gz, &namespace.base, &wip_members, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
38103868 error.OutOfMemory => return error.OutOfMemory,
38113869 error.AnalysisFail => {},
38123870 };
38133871 continue;
38143872 },
38153873 .simple_var_decl => {
3816 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
3874 astgen.globalVarDecl(gz, &namespace.base, &wip_members, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
38173875 error.OutOfMemory => return error.OutOfMemory,
38183876 error.AnalysisFail => {},
38193877 };
38203878 continue;
38213879 },
38223880 .aligned_var_decl => {
3823 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
3881 astgen.globalVarDecl(gz, &namespace.base, &wip_members, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
38243882 error.OutOfMemory => return error.OutOfMemory,
38253883 error.AnalysisFail => {},
38263884 };
......@@ -3828,21 +3886,21 @@ fn structDeclInner(
38283886 },
38293887
38303888 .@"comptime" => {
3831 astgen.comptimeDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
3889 astgen.comptimeDecl(gz, &namespace.base, &wip_members, member_node) catch |err| switch (err) {
38323890 error.OutOfMemory => return error.OutOfMemory,
38333891 error.AnalysisFail => {},
38343892 };
38353893 continue;
38363894 },
38373895 .@"usingnamespace" => {
3838 astgen.usingnamespaceDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
3896 astgen.usingnamespaceDecl(gz, &namespace.base, &wip_members, member_node) catch |err| switch (err) {
38393897 error.OutOfMemory => return error.OutOfMemory,
38403898 error.AnalysisFail => {},
38413899 };
38423900 continue;
38433901 },
38443902 .test_decl => {
3845 astgen.testDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
3903 astgen.testDecl(gz, &namespace.base, &wip_members, member_node) catch |err| switch (err) {
38463904 error.OutOfMemory => return error.OutOfMemory,
38473905 error.AnalysisFail => {},
38483906 };
......@@ -3850,14 +3908,9 @@ fn structDeclInner(
38503908 },
38513909 else => unreachable,
38523910 };
3853 if (field_index % fields_per_u32 == 0 and field_index != 0) {
3854 try bit_bag.append(gpa, cur_bit_bag);
3855 cur_bit_bag = 0;
3856 }
3857 try fields_data.ensureUnusedCapacity(gpa, 4);
38583911
38593912 const field_name = try astgen.identAsString(member.ast.name_token);
3860 fields_data.appendAssumeCapacity(field_name);
3913 wip_members.appendToField(field_name);
38613914
38623915 if (member.ast.type_expr == 0) {
38633916 return astgen.failTok(member.ast.name_token, "struct field missing type", .{});
......@@ -3867,7 +3920,7 @@ fn structDeclInner(
38673920 .none
38683921 else
38693922 try typeExpr(&block_scope, &namespace.base, member.ast.type_expr);
3870 fields_data.appendAssumeCapacity(@enumToInt(field_type));
3923 wip_members.appendToField(@enumToInt(field_type));
38713924
38723925 known_has_bits = known_has_bits or nodeImpliesRuntimeBits(tree, member.ast.type_expr);
38733926
......@@ -3875,39 +3928,22 @@ fn structDeclInner(
38753928 const have_value = member.ast.value_expr != 0;
38763929 const is_comptime = member.comptime_token != null;
38773930 const unused = false;
3878 cur_bit_bag = (cur_bit_bag >> bits_per_field) |
3879 (@as(u32, @boolToInt(have_align)) << 28) |
3880 (@as(u32, @boolToInt(have_value)) << 29) |
3881 (@as(u32, @boolToInt(is_comptime)) << 30) |
3882 (@as(u32, @boolToInt(unused)) << 31);
3931 wip_members.nextField(bits_per_field, .{ have_align, have_value, is_comptime, unused });
38833932
38843933 if (have_align) {
38853934 const align_inst = try expr(&block_scope, &namespace.base, align_rl, member.ast.align_expr);
3886 fields_data.appendAssumeCapacity(@enumToInt(align_inst));
3935 wip_members.appendToField(@enumToInt(align_inst));
38873936 }
38883937 if (have_value) {
38893938 const rl: ResultLoc = if (field_type == .none) .none else .{ .ty = field_type };
38903939
38913940 const default_inst = try expr(&block_scope, &namespace.base, rl, member.ast.value_expr);
3892 fields_data.appendAssumeCapacity(@enumToInt(default_inst));
3941 wip_members.appendToField(@enumToInt(default_inst));
38933942 } else if (member.comptime_token) |comptime_token| {
38943943 return astgen.failTok(comptime_token, "comptime field without default initialization value", .{});
38953944 }
3896
3897 field_index += 1;
3898 }
3899 {
3900 const empty_slot_count = fields_per_u32 - (field_index % fields_per_u32);
3901 if (empty_slot_count < fields_per_u32) {
3902 cur_bit_bag >>= @intCast(u5, empty_slot_count * bits_per_field);
3903 }
3904 }
3905 {
3906 const empty_slot_count = WipDecls.fields_per_u32 - (wip_decls.decl_index % WipDecls.fields_per_u32);
3907 if (empty_slot_count < WipDecls.fields_per_u32) {
3908 wip_decls.cur_bit_bag >>= @intCast(u5, empty_slot_count * WipDecls.bits_per_field);
3909 }
39103945 }
3946 assert(wip_members.decl_index == decl_count and wip_members.field_index == field_count);
39113947
39123948 if (block_scope.instructions.items.len != 0) {
39133949 _ = try block_scope.addBreak(.break_inline, decl_inst, .void_value);
......@@ -3917,36 +3953,18 @@ fn structDeclInner(
39173953 .src_node = node,
39183954 .layout = layout,
39193955 .body_len = @intCast(u32, block_scope.instructions.items.len),
3920 .fields_len = @intCast(u32, field_index),
3921 .decls_len = @intCast(u32, wip_decls.decl_index),
3956 .fields_len = field_count,
3957 .decls_len = decl_count,
39223958 .known_has_bits = known_has_bits,
39233959 });
39243960
3925 // zig fmt: off
3926 try astgen.extra.ensureUnusedCapacity(gpa,
3927 bit_bag.items.len +
3928 @boolToInt(wip_decls.decl_index != 0) +
3929 wip_decls.payload.items.len +
3930 block_scope.instructions.items.len +
3931 wip_decls.bit_bag.items.len +
3932 @boolToInt(field_index != 0) +
3933 fields_data.items.len
3934 );
3935 // zig fmt: on
3936
3937 astgen.extra.appendSliceAssumeCapacity(wip_decls.bit_bag.items); // Likely empty.
3938 if (wip_decls.decl_index != 0) {
3939 astgen.extra.appendAssumeCapacity(wip_decls.cur_bit_bag);
3940 }
3941 astgen.extra.appendSliceAssumeCapacity(wip_decls.payload.items);
3942
3961 wip_members.finishBits(bits_per_field);
3962 const decls_slice = wip_members.declsSlice();
3963 const fields_slice = wip_members.fieldsSlice();
3964 try astgen.extra.ensureUnusedCapacity(gpa, decls_slice.len + block_scope.instructions.items.len + fields_slice.len);
3965 astgen.extra.appendSliceAssumeCapacity(decls_slice);
39433966 astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items);
3944
3945 astgen.extra.appendSliceAssumeCapacity(bit_bag.items); // Likely empty.
3946 if (field_index != 0) {
3947 astgen.extra.appendAssumeCapacity(cur_bit_bag);
3948 }
3949 astgen.extra.appendSliceAssumeCapacity(fields_data.items);
3967 astgen.extra.appendSliceAssumeCapacity(fields_slice);
39503968
39513969 return indexToRef(decl_inst);
39523970}
......@@ -3989,29 +4007,19 @@ fn unionDeclInner(
39894007 };
39904008 defer block_scope.instructions.deinit(gpa);
39914009
3992 try astgen.scanDecls(&namespace, members);
4010 const decl_count = try astgen.scanDecls(&namespace, members);
4011 const field_count = @intCast(u32, members.len - decl_count);
39934012
39944013 const arg_inst: Zir.Inst.Ref = if (arg_node != 0)
39954014 try typeExpr(&block_scope, &namespace.base, arg_node)
39964015 else
39974016 .none;
39984017
3999 var wip_decls: WipDecls = .{};
4000 defer wip_decls.deinit(gpa);
4001
4002 // We don't know which members are fields until we iterate, so cannot do
4003 // an accurate ensureTotalCapacity yet.
4004 var fields_data = ArrayListUnmanaged(u32){};
4005 defer fields_data.deinit(gpa);
4006
40074018 const bits_per_field = 4;
4008 const fields_per_u32 = 32 / bits_per_field;
4009 // We only need this if there are greater than fields_per_u32 fields.
4010 var bit_bag = ArrayListUnmanaged(u32){};
4011 defer bit_bag.deinit(gpa);
4019 const max_field_size = 4;
4020 var wip_members = try WipMembers.init(gpa, decl_count, field_count, bits_per_field, max_field_size);
4021 defer wip_members.deinit(gpa);
40124022
4013 var cur_bit_bag: u32 = 0;
4014 var field_index: usize = 0;
40154023 for (members) |member_node| {
40164024 const member = switch (node_tags[member_node]) {
40174025 .container_field_init => tree.containerFieldInit(member_node),
......@@ -4024,14 +4032,14 @@ fn unionDeclInner(
40244032 switch (node_tags[fn_proto]) {
40254033 .fn_proto_simple => {
40264034 var params: [1]Ast.Node.Index = undefined;
4027 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
4035 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
40284036 error.OutOfMemory => return error.OutOfMemory,
40294037 error.AnalysisFail => {},
40304038 };
40314039 continue;
40324040 },
40334041 .fn_proto_multi => {
4034 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
4042 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
40354043 error.OutOfMemory => return error.OutOfMemory,
40364044 error.AnalysisFail => {},
40374045 };
......@@ -4039,14 +4047,14 @@ fn unionDeclInner(
40394047 },
40404048 .fn_proto_one => {
40414049 var params: [1]Ast.Node.Index = undefined;
4042 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
4050 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
40434051 error.OutOfMemory => return error.OutOfMemory,
40444052 error.AnalysisFail => {},
40454053 };
40464054 continue;
40474055 },
40484056 .fn_proto => {
4049 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
4057 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
40504058 error.OutOfMemory => return error.OutOfMemory,
40514059 error.AnalysisFail => {},
40524060 };
......@@ -4057,14 +4065,14 @@ fn unionDeclInner(
40574065 },
40584066 .fn_proto_simple => {
40594067 var params: [1]Ast.Node.Index = undefined;
4060 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
4068 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
40614069 error.OutOfMemory => return error.OutOfMemory,
40624070 error.AnalysisFail => {},
40634071 };
40644072 continue;
40654073 },
40664074 .fn_proto_multi => {
4067 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
4075 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
40684076 error.OutOfMemory => return error.OutOfMemory,
40694077 error.AnalysisFail => {},
40704078 };
......@@ -4072,14 +4080,14 @@ fn unionDeclInner(
40724080 },
40734081 .fn_proto_one => {
40744082 var params: [1]Ast.Node.Index = undefined;
4075 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
4083 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
40764084 error.OutOfMemory => return error.OutOfMemory,
40774085 error.AnalysisFail => {},
40784086 };
40794087 continue;
40804088 },
40814089 .fn_proto => {
4082 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
4090 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
40834091 error.OutOfMemory => return error.OutOfMemory,
40844092 error.AnalysisFail => {},
40854093 };
......@@ -4087,28 +4095,28 @@ fn unionDeclInner(
40874095 },
40884096
40894097 .global_var_decl => {
4090 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
4098 astgen.globalVarDecl(gz, &namespace.base, &wip_members, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
40914099 error.OutOfMemory => return error.OutOfMemory,
40924100 error.AnalysisFail => {},
40934101 };
40944102 continue;
40954103 },
40964104 .local_var_decl => {
4097 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
4105 astgen.globalVarDecl(gz, &namespace.base, &wip_members, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
40984106 error.OutOfMemory => return error.OutOfMemory,
40994107 error.AnalysisFail => {},
41004108 };
41014109 continue;
41024110 },
41034111 .simple_var_decl => {
4104 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
4112 astgen.globalVarDecl(gz, &namespace.base, &wip_members, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
41054113 error.OutOfMemory => return error.OutOfMemory,
41064114 error.AnalysisFail => {},
41074115 };
41084116 continue;
41094117 },
41104118 .aligned_var_decl => {
4111 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
4119 astgen.globalVarDecl(gz, &namespace.base, &wip_members, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
41124120 error.OutOfMemory => return error.OutOfMemory,
41134121 error.AnalysisFail => {},
41144122 };
......@@ -4116,21 +4124,21 @@ fn unionDeclInner(
41164124 },
41174125
41184126 .@"comptime" => {
4119 astgen.comptimeDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
4127 astgen.comptimeDecl(gz, &namespace.base, &wip_members, member_node) catch |err| switch (err) {
41204128 error.OutOfMemory => return error.OutOfMemory,
41214129 error.AnalysisFail => {},
41224130 };
41234131 continue;
41244132 },
41254133 .@"usingnamespace" => {
4126 astgen.usingnamespaceDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
4134 astgen.usingnamespaceDecl(gz, &namespace.base, &wip_members, member_node) catch |err| switch (err) {
41274135 error.OutOfMemory => return error.OutOfMemory,
41284136 error.AnalysisFail => {},
41294137 };
41304138 continue;
41314139 },
41324140 .test_decl => {
4133 astgen.testDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
4141 astgen.testDecl(gz, &namespace.base, &wip_members, member_node) catch |err| switch (err) {
41344142 error.OutOfMemory => return error.OutOfMemory,
41354143 error.AnalysisFail => {},
41364144 };
......@@ -4138,40 +4146,31 @@ fn unionDeclInner(
41384146 },
41394147 else => unreachable,
41404148 };
4141 if (field_index % fields_per_u32 == 0 and field_index != 0) {
4142 try bit_bag.append(gpa, cur_bit_bag);
4143 cur_bit_bag = 0;
4144 }
41454149 if (member.comptime_token) |comptime_token| {
41464150 return astgen.failTok(comptime_token, "union fields cannot be marked comptime", .{});
41474151 }
4148 try fields_data.ensureUnusedCapacity(gpa, 4);
41494152
41504153 const field_name = try astgen.identAsString(member.ast.name_token);
4151 fields_data.appendAssumeCapacity(field_name);
4154 wip_members.appendToField(field_name);
41524155
41534156 const have_type = member.ast.type_expr != 0;
41544157 const have_align = member.ast.align_expr != 0;
41554158 const have_value = member.ast.value_expr != 0;
41564159 const unused = false;
4157 cur_bit_bag = (cur_bit_bag >> bits_per_field) |
4158 (@as(u32, @boolToInt(have_type)) << 28) |
4159 (@as(u32, @boolToInt(have_align)) << 29) |
4160 (@as(u32, @boolToInt(have_value)) << 30) |
4161 (@as(u32, @boolToInt(unused)) << 31);
4160 wip_members.nextField(bits_per_field, .{ have_type, have_align, have_value, unused });
41624161
41634162 if (have_type) {
41644163 const field_type: Zir.Inst.Ref = if (node_tags[member.ast.type_expr] == .@"anytype")
41654164 .none
41664165 else
41674166 try typeExpr(&block_scope, &namespace.base, member.ast.type_expr);
4168 fields_data.appendAssumeCapacity(@enumToInt(field_type));
4167 wip_members.appendToField(@enumToInt(field_type));
41694168 } else if (arg_inst == .none and !have_auto_enum) {
41704169 return astgen.failNode(member_node, "union field missing type", .{});
41714170 }
41724171 if (have_align) {
41734172 const align_inst = try expr(&block_scope, &block_scope.base, .{ .ty = .u32_type }, member.ast.align_expr);
4174 fields_data.appendAssumeCapacity(@enumToInt(align_inst));
4173 wip_members.appendToField(@enumToInt(align_inst));
41754174 }
41764175 if (have_value) {
41774176 if (arg_inst == .none) {
......@@ -4203,26 +4202,13 @@ fn unionDeclInner(
42034202 );
42044203 }
42054204 const tag_value = try expr(&block_scope, &block_scope.base, .{ .ty = arg_inst }, member.ast.value_expr);
4206 fields_data.appendAssumeCapacity(@enumToInt(tag_value));
4205 wip_members.appendToField(@enumToInt(tag_value));
42074206 }
4208
4209 field_index += 1;
42104207 }
4211 if (field_index == 0) {
4208 assert(wip_members.decl_index == decl_count and wip_members.field_index == field_count);
4209 if (field_count == 0) {
42124210 return astgen.failNode(node, "union declarations must have at least one tag", .{});
42134211 }
4214 {
4215 const empty_slot_count = fields_per_u32 - (field_index % fields_per_u32);
4216 if (empty_slot_count < fields_per_u32) {
4217 cur_bit_bag >>= @intCast(u5, empty_slot_count * bits_per_field);
4218 }
4219 }
4220 {
4221 const empty_slot_count = WipDecls.fields_per_u32 - (wip_decls.decl_index % WipDecls.fields_per_u32);
4222 if (empty_slot_count < WipDecls.fields_per_u32) {
4223 wip_decls.cur_bit_bag >>= @intCast(u5, empty_slot_count * WipDecls.bits_per_field);
4224 }
4225 }
42264212
42274213 if (block_scope.instructions.items.len != 0) {
42284214 _ = try block_scope.addBreak(.break_inline, decl_inst, .void_value);
......@@ -4233,34 +4219,18 @@ fn unionDeclInner(
42334219 .layout = layout,
42344220 .tag_type = arg_inst,
42354221 .body_len = @intCast(u32, block_scope.instructions.items.len),
4236 .fields_len = @intCast(u32, field_index),
4237 .decls_len = @intCast(u32, wip_decls.decl_index),
4222 .fields_len = field_count,
4223 .decls_len = decl_count,
42384224 .auto_enum_tag = have_auto_enum,
42394225 });
42404226
4241 // zig fmt: off
4242 try astgen.extra.ensureUnusedCapacity(gpa,
4243 bit_bag.items.len +
4244 @boolToInt(wip_decls.decl_index != 0) +
4245 wip_decls.payload.items.len +
4246 block_scope.instructions.items.len +
4247 wip_decls.bit_bag.items.len +
4248 1 + // cur_bit_bag
4249 fields_data.items.len
4250 );
4251 // zig fmt: on
4252
4253 astgen.extra.appendSliceAssumeCapacity(wip_decls.bit_bag.items); // Likely empty.
4254 if (wip_decls.decl_index != 0) {
4255 astgen.extra.appendAssumeCapacity(wip_decls.cur_bit_bag);
4256 }
4257 astgen.extra.appendSliceAssumeCapacity(wip_decls.payload.items);
4258
4227 wip_members.finishBits(bits_per_field);
4228 const decls_slice = wip_members.declsSlice();
4229 const fields_slice = wip_members.fieldsSlice();
4230 try astgen.extra.ensureUnusedCapacity(gpa, decls_slice.len + block_scope.instructions.items.len + fields_slice.len);
4231 astgen.extra.appendSliceAssumeCapacity(decls_slice);
42594232 astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items);
4260
4261 astgen.extra.appendSliceAssumeCapacity(bit_bag.items); // Likely empty.
4262 astgen.extra.appendAssumeCapacity(cur_bit_bag);
4263 astgen.extra.appendSliceAssumeCapacity(fields_data.items);
4233 astgen.extra.appendSliceAssumeCapacity(fields_slice);
42644234
42654235 return indexToRef(decl_inst);
42664236}
......@@ -4434,27 +4404,18 @@ fn containerDecl(
44344404 };
44354405 defer block_scope.instructions.deinit(gpa);
44364406
4437 try astgen.scanDecls(&namespace, container_decl.ast.members);
4407 _ = try astgen.scanDecls(&namespace, container_decl.ast.members);
44384408
44394409 const arg_inst: Zir.Inst.Ref = if (container_decl.ast.arg != 0)
44404410 try comptimeExpr(&block_scope, &namespace.base, .{ .ty = .type_type }, container_decl.ast.arg)
44414411 else
44424412 .none;
44434413
4444 var wip_decls: WipDecls = .{};
4445 defer wip_decls.deinit(gpa);
4446
4447 var fields_data = ArrayListUnmanaged(u32){};
4448 defer fields_data.deinit(gpa);
4449
4450 try fields_data.ensureTotalCapacity(gpa, counts.total_fields + counts.values);
4451
4452 // We only need this if there are greater than 32 fields.
4453 var bit_bag = ArrayListUnmanaged(u32){};
4454 defer bit_bag.deinit(gpa);
4414 const bits_per_field = 1;
4415 const max_field_size = 2;
4416 var wip_members = try WipMembers.init(gpa, @intCast(u32, counts.decls), @intCast(u32, counts.total_fields), bits_per_field, max_field_size);
4417 defer wip_members.deinit(gpa);
44554418
4456 var cur_bit_bag: u32 = 0;
4457 var field_index: usize = 0;
44584419 for (container_decl.ast.members) |member_node| {
44594420 if (member_node == counts.nonexhaustive_node)
44604421 continue;
......@@ -4469,14 +4430,14 @@ fn containerDecl(
44694430 switch (node_tags[fn_proto]) {
44704431 .fn_proto_simple => {
44714432 var params: [1]Ast.Node.Index = undefined;
4472 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
4433 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
44734434 error.OutOfMemory => return error.OutOfMemory,
44744435 error.AnalysisFail => {},
44754436 };
44764437 continue;
44774438 },
44784439 .fn_proto_multi => {
4479 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
4440 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
44804441 error.OutOfMemory => return error.OutOfMemory,
44814442 error.AnalysisFail => {},
44824443 };
......@@ -4484,14 +4445,14 @@ fn containerDecl(
44844445 },
44854446 .fn_proto_one => {
44864447 var params: [1]Ast.Node.Index = undefined;
4487 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
4448 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
44884449 error.OutOfMemory => return error.OutOfMemory,
44894450 error.AnalysisFail => {},
44904451 };
44914452 continue;
44924453 },
44934454 .fn_proto => {
4494 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
4455 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
44954456 error.OutOfMemory => return error.OutOfMemory,
44964457 error.AnalysisFail => {},
44974458 };
......@@ -4502,14 +4463,14 @@ fn containerDecl(
45024463 },
45034464 .fn_proto_simple => {
45044465 var params: [1]Ast.Node.Index = undefined;
4505 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
4466 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
45064467 error.OutOfMemory => return error.OutOfMemory,
45074468 error.AnalysisFail => {},
45084469 };
45094470 continue;
45104471 },
45114472 .fn_proto_multi => {
4512 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
4473 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
45134474 error.OutOfMemory => return error.OutOfMemory,
45144475 error.AnalysisFail => {},
45154476 };
......@@ -4517,14 +4478,14 @@ fn containerDecl(
45174478 },
45184479 .fn_proto_one => {
45194480 var params: [1]Ast.Node.Index = undefined;
4520 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
4481 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
45214482 error.OutOfMemory => return error.OutOfMemory,
45224483 error.AnalysisFail => {},
45234484 };
45244485 continue;
45254486 },
45264487 .fn_proto => {
4527 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
4488 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
45284489 error.OutOfMemory => return error.OutOfMemory,
45294490 error.AnalysisFail => {},
45304491 };
......@@ -4532,28 +4493,28 @@ fn containerDecl(
45324493 },
45334494
45344495 .global_var_decl => {
4535 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
4496 astgen.globalVarDecl(gz, &namespace.base, &wip_members, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
45364497 error.OutOfMemory => return error.OutOfMemory,
45374498 error.AnalysisFail => {},
45384499 };
45394500 continue;
45404501 },
45414502 .local_var_decl => {
4542 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
4503 astgen.globalVarDecl(gz, &namespace.base, &wip_members, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
45434504 error.OutOfMemory => return error.OutOfMemory,
45444505 error.AnalysisFail => {},
45454506 };
45464507 continue;
45474508 },
45484509 .simple_var_decl => {
4549 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
4510 astgen.globalVarDecl(gz, &namespace.base, &wip_members, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
45504511 error.OutOfMemory => return error.OutOfMemory,
45514512 error.AnalysisFail => {},
45524513 };
45534514 continue;
45544515 },
45554516 .aligned_var_decl => {
4556 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
4517 astgen.globalVarDecl(gz, &namespace.base, &wip_members, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
45574518 error.OutOfMemory => return error.OutOfMemory,
45584519 error.AnalysisFail => {},
45594520 };
......@@ -4561,21 +4522,21 @@ fn containerDecl(
45614522 },
45624523
45634524 .@"comptime" => {
4564 astgen.comptimeDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
4525 astgen.comptimeDecl(gz, &namespace.base, &wip_members, member_node) catch |err| switch (err) {
45654526 error.OutOfMemory => return error.OutOfMemory,
45664527 error.AnalysisFail => {},
45674528 };
45684529 continue;
45694530 },
45704531 .@"usingnamespace" => {
4571 astgen.usingnamespaceDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
4532 astgen.usingnamespaceDecl(gz, &namespace.base, &wip_members, member_node) catch |err| switch (err) {
45724533 error.OutOfMemory => return error.OutOfMemory,
45734534 error.AnalysisFail => {},
45744535 };
45754536 continue;
45764537 },
45774538 .test_decl => {
4578 astgen.testDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
4539 astgen.testDecl(gz, &namespace.base, &wip_members, member_node) catch |err| switch (err) {
45794540 error.OutOfMemory => return error.OutOfMemory,
45804541 error.AnalysisFail => {},
45814542 };
......@@ -4583,20 +4544,15 @@ fn containerDecl(
45834544 },
45844545 else => unreachable,
45854546 };
4586 if (field_index % 32 == 0 and field_index != 0) {
4587 try bit_bag.append(gpa, cur_bit_bag);
4588 cur_bit_bag = 0;
4589 }
45904547 assert(member.comptime_token == null);
45914548 assert(member.ast.type_expr == 0);
45924549 assert(member.ast.align_expr == 0);
45934550
45944551 const field_name = try astgen.identAsString(member.ast.name_token);
4595 fields_data.appendAssumeCapacity(field_name);
4552 wip_members.appendToField(field_name);
45964553
45974554 const have_value = member.ast.value_expr != 0;
4598 cur_bit_bag = (cur_bit_bag >> 1) |
4599 (@as(u32, @boolToInt(have_value)) << 31);
4555 wip_members.nextField(bits_per_field, .{have_value});
46004556
46014557 if (have_value) {
46024558 if (arg_inst == .none) {
......@@ -4614,23 +4570,10 @@ fn containerDecl(
46144570 );
46154571 }
46164572 const tag_value_inst = try expr(&block_scope, &namespace.base, .{ .ty = arg_inst }, member.ast.value_expr);
4617 fields_data.appendAssumeCapacity(@enumToInt(tag_value_inst));
4618 }
4619
4620 field_index += 1;
4621 }
4622 {
4623 const empty_slot_count = 32 - (field_index % 32);
4624 if (empty_slot_count < 32) {
4625 cur_bit_bag >>= @intCast(u5, empty_slot_count);
4626 }
4627 }
4628 {
4629 const empty_slot_count = WipDecls.fields_per_u32 - (wip_decls.decl_index % WipDecls.fields_per_u32);
4630 if (empty_slot_count < WipDecls.fields_per_u32) {
4631 wip_decls.cur_bit_bag >>= @intCast(u5, empty_slot_count * WipDecls.bits_per_field);
4573 wip_members.appendToField(@enumToInt(tag_value_inst));
46324574 }
46334575 }
4576 assert(wip_members.decl_index == counts.decls and wip_members.field_index == counts.total_fields);
46344577
46354578 if (block_scope.instructions.items.len != 0) {
46364579 _ = try block_scope.addBreak(.break_inline, decl_inst, .void_value);
......@@ -4641,32 +4584,17 @@ fn containerDecl(
46414584 .nonexhaustive = nonexhaustive,
46424585 .tag_type = arg_inst,
46434586 .body_len = @intCast(u32, block_scope.instructions.items.len),
4644 .fields_len = @intCast(u32, field_index),
4645 .decls_len = @intCast(u32, wip_decls.decl_index),
4587 .fields_len = @intCast(u32, counts.total_fields),
4588 .decls_len = @intCast(u32, counts.decls),
46464589 });
46474590
4648 // zig fmt: off
4649 try astgen.extra.ensureUnusedCapacity(gpa,
4650 bit_bag.items.len +
4651 @boolToInt(wip_decls.decl_index != 0) +
4652 wip_decls.payload.items.len +
4653 block_scope.instructions.items.len +
4654 wip_decls.bit_bag.items.len +
4655 1 + // cur_bit_bag
4656 fields_data.items.len
4657 );
4658 // zig fmt: on
4659
4660 astgen.extra.appendSliceAssumeCapacity(wip_decls.bit_bag.items); // Likely empty.
4661 if (wip_decls.decl_index != 0) {
4662 astgen.extra.appendAssumeCapacity(wip_decls.cur_bit_bag);
4663 }
4664 astgen.extra.appendSliceAssumeCapacity(wip_decls.payload.items);
4665
4591 wip_members.finishBits(bits_per_field);
4592 const decls_slice = wip_members.declsSlice();
4593 const fields_slice = wip_members.fieldsSlice();
4594 try astgen.extra.ensureUnusedCapacity(gpa, decls_slice.len + block_scope.instructions.items.len + fields_slice.len);
4595 astgen.extra.appendSliceAssumeCapacity(decls_slice);
46664596 astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items);
4667 astgen.extra.appendSliceAssumeCapacity(bit_bag.items); // Likely empty.
4668 astgen.extra.appendAssumeCapacity(cur_bit_bag);
4669 astgen.extra.appendSliceAssumeCapacity(fields_data.items);
4597 astgen.extra.appendSliceAssumeCapacity(fields_slice);
46704598
46714599 return rvalue(gz, rl, indexToRef(decl_inst), node);
46724600 },
......@@ -4683,10 +4611,10 @@ fn containerDecl(
46834611 };
46844612 defer namespace.deinit(gpa);
46854613
4686 try astgen.scanDecls(&namespace, container_decl.ast.members);
4614 const decl_count = try astgen.scanDecls(&namespace, container_decl.ast.members);
46874615
4688 var wip_decls: WipDecls = .{};
4689 defer wip_decls.deinit(gpa);
4616 var wip_members = try WipMembers.init(gpa, decl_count, 0, 0, 0);
4617 defer wip_members.deinit(gpa);
46904618
46914619 for (container_decl.ast.members) |member_node| {
46924620 switch (node_tags[member_node]) {
......@@ -4698,14 +4626,14 @@ fn containerDecl(
46984626 switch (node_tags[fn_proto]) {
46994627 .fn_proto_simple => {
47004628 var params: [1]Ast.Node.Index = undefined;
4701 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
4629 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
47024630 error.OutOfMemory => return error.OutOfMemory,
47034631 error.AnalysisFail => {},
47044632 };
47054633 continue;
47064634 },
47074635 .fn_proto_multi => {
4708 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
4636 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
47094637 error.OutOfMemory => return error.OutOfMemory,
47104638 error.AnalysisFail => {},
47114639 };
......@@ -4713,14 +4641,14 @@ fn containerDecl(
47134641 },
47144642 .fn_proto_one => {
47154643 var params: [1]Ast.Node.Index = undefined;
4716 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
4644 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
47174645 error.OutOfMemory => return error.OutOfMemory,
47184646 error.AnalysisFail => {},
47194647 };
47204648 continue;
47214649 },
47224650 .fn_proto => {
4723 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
4651 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
47244652 error.OutOfMemory => return error.OutOfMemory,
47254653 error.AnalysisFail => {},
47264654 };
......@@ -4731,14 +4659,14 @@ fn containerDecl(
47314659 },
47324660 .fn_proto_simple => {
47334661 var params: [1]Ast.Node.Index = undefined;
4734 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
4662 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
47354663 error.OutOfMemory => return error.OutOfMemory,
47364664 error.AnalysisFail => {},
47374665 };
47384666 continue;
47394667 },
47404668 .fn_proto_multi => {
4741 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
4669 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
47424670 error.OutOfMemory => return error.OutOfMemory,
47434671 error.AnalysisFail => {},
47444672 };
......@@ -4746,14 +4674,14 @@ fn containerDecl(
47464674 },
47474675 .fn_proto_one => {
47484676 var params: [1]Ast.Node.Index = undefined;
4749 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
4677 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
47504678 error.OutOfMemory => return error.OutOfMemory,
47514679 error.AnalysisFail => {},
47524680 };
47534681 continue;
47544682 },
47554683 .fn_proto => {
4756 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
4684 astgen.fnDecl(gz, &namespace.base, &wip_members, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
47574685 error.OutOfMemory => return error.OutOfMemory,
47584686 error.AnalysisFail => {},
47594687 };
......@@ -4761,28 +4689,28 @@ fn containerDecl(
47614689 },
47624690
47634691 .global_var_decl => {
4764 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
4692 astgen.globalVarDecl(gz, &namespace.base, &wip_members, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
47654693 error.OutOfMemory => return error.OutOfMemory,
47664694 error.AnalysisFail => {},
47674695 };
47684696 continue;
47694697 },
47704698 .local_var_decl => {
4771 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
4699 astgen.globalVarDecl(gz, &namespace.base, &wip_members, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
47724700 error.OutOfMemory => return error.OutOfMemory,
47734701 error.AnalysisFail => {},
47744702 };
47754703 continue;
47764704 },
47774705 .simple_var_decl => {
4778 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
4706 astgen.globalVarDecl(gz, &namespace.base, &wip_members, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
47794707 error.OutOfMemory => return error.OutOfMemory,
47804708 error.AnalysisFail => {},
47814709 };
47824710 continue;
47834711 },
47844712 .aligned_var_decl => {
4785 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
4713 astgen.globalVarDecl(gz, &namespace.base, &wip_members, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
47864714 error.OutOfMemory => return error.OutOfMemory,
47874715 error.AnalysisFail => {},
47884716 };
......@@ -4790,21 +4718,21 @@ fn containerDecl(
47904718 },
47914719
47924720 .@"comptime" => {
4793 astgen.comptimeDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
4721 astgen.comptimeDecl(gz, &namespace.base, &wip_members, member_node) catch |err| switch (err) {
47944722 error.OutOfMemory => return error.OutOfMemory,
47954723 error.AnalysisFail => {},
47964724 };
47974725 continue;
47984726 },
47994727 .@"usingnamespace" => {
4800 astgen.usingnamespaceDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
4728 astgen.usingnamespaceDecl(gz, &namespace.base, &wip_members, member_node) catch |err| switch (err) {
48014729 error.OutOfMemory => return error.OutOfMemory,
48024730 error.AnalysisFail => {},
48034731 };
48044732 continue;
48054733 },
48064734 .test_decl => {
4807 astgen.testDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
4735 astgen.testDecl(gz, &namespace.base, &wip_members, member_node) catch |err| switch (err) {
48084736 error.OutOfMemory => return error.OutOfMemory,
48094737 error.AnalysisFail => {},
48104738 };
......@@ -4813,31 +4741,17 @@ fn containerDecl(
48134741 else => unreachable,
48144742 }
48154743 }
4816 {
4817 const empty_slot_count = WipDecls.fields_per_u32 - (wip_decls.decl_index % WipDecls.fields_per_u32);
4818 if (empty_slot_count < WipDecls.fields_per_u32) {
4819 wip_decls.cur_bit_bag >>= @intCast(u5, empty_slot_count * WipDecls.bits_per_field);
4820 }
4821 }
4744 assert(wip_members.decl_index == decl_count);
48224745
48234746 try gz.setOpaque(decl_inst, .{
48244747 .src_node = node,
4825 .decls_len = @intCast(u32, wip_decls.decl_index),
4748 .decls_len = decl_count,
48264749 });
48274750
4828 // zig fmt: off
4829 try astgen.extra.ensureUnusedCapacity(gpa,
4830 wip_decls.bit_bag.items.len +
4831 @boolToInt(wip_decls.decl_index != 0) +
4832 wip_decls.payload.items.len
4833 );
4834 // zig fmt: on
4835
4836 astgen.extra.appendSliceAssumeCapacity(wip_decls.bit_bag.items); // Likely empty.
4837 if (wip_decls.decl_index != 0) {
4838 astgen.extra.appendAssumeCapacity(wip_decls.cur_bit_bag);
4839 }
4840 astgen.extra.appendSliceAssumeCapacity(wip_decls.payload.items);
4751 wip_members.finishBits(0);
4752 const decls_slice = wip_members.declsSlice();
4753 try astgen.extra.ensureUnusedCapacity(gpa, decls_slice.len);
4754 astgen.extra.appendSliceAssumeCapacity(decls_slice);
48414755
48424756 return rvalue(gz, rl, indexToRef(decl_inst), node);
48434757 },
......@@ -10436,12 +10350,13 @@ fn advanceSourceCursor(astgen: *AstGen, source: []const u8, end: usize) void {
1043610350 astgen.source_column = column;
1043710351}
1043810352
10439fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast.Node.Index) !void {
10353fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast.Node.Index) !u32 {
1044010354 const gpa = astgen.gpa;
1044110355 const tree = astgen.tree;
1044210356 const node_tags = tree.nodes.items(.tag);
1044310357 const main_tokens = tree.nodes.items(.main_token);
1044410358 const token_tags = tree.tokens.items(.tag);
10359 var decl_count: u32 = 0;
1044510360 for (members) |member_node| {
1044610361 const name_token = switch (node_tags[member_node]) {
1044710362 .fn_proto_simple,
......@@ -10452,9 +10367,13 @@ fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast.
1045210367 .local_var_decl,
1045310368 .simple_var_decl,
1045410369 .aligned_var_decl,
10455 => main_tokens[member_node] + 1,
10370 => blk: {
10371 decl_count += 1;
10372 break :blk main_tokens[member_node] + 1;
10373 },
1045610374
1045710375 .fn_decl => blk: {
10376 decl_count += 1;
1045810377 const ident = main_tokens[member_node] + 1;
1045910378 if (token_tags[ident] != .identifier) {
1046010379 switch (astgen.failNode(member_node, "missing function name", .{})) {
......@@ -10465,6 +10384,11 @@ fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast.
1046510384 break :blk ident;
1046610385 },
1046710386
10387 .@"comptime", .@"usingnamespace", .test_decl => {
10388 decl_count += 1;
10389 continue;
10390 },
10391
1046810392 else => continue,
1046910393 };
1047010394
......@@ -10498,4 +10422,5 @@ fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast.
1049810422 }
1049910423 gop.value_ptr.* = member_node;
1050010424 }
10425 return decl_count;
1050110426}