| ... | ... | @@ -2995,38 +2995,112 @@ fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.I |
| 2995 | 2995 | return rvalue(gz, rl, result, node); |
| 2996 | 2996 | } |
| 2997 | 2997 | |
| 2998 | | const WipDecls = struct { |
| 2999 | | decl_index: usize = 0, |
| 3000 | | cur_bit_bag: u32 = 0, |
| 3001 | | bit_bag: ArrayListUnmanaged(u32) = .{}, |
| 3002 | | payload: ArrayListUnmanaged(u32) = .{}, |
| 2998 | const 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 | } |
| 3003 | 3033 | |
| 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) | |
| 3020 | 3039 | (@as(u32, @boolToInt(is_pub)) << 28) | |
| 3021 | 3040 | (@as(u32, @boolToInt(is_export)) << 29) | |
| 3022 | 3041 | (@as(u32, @boolToInt(has_align)) << 30) | |
| 3023 | 3042 | (@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; |
| 3025 | 3076 | } |
| 3026 | 3077 | |
| 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); |
| 3030 | 3104 | } |
| 3031 | 3105 | }; |
| 3032 | 3106 | |
| ... | ... | @@ -3034,7 +3108,7 @@ fn fnDecl( |
| 3034 | 3108 | astgen: *AstGen, |
| 3035 | 3109 | gz: *GenZir, |
| 3036 | 3110 | scope: *Scope, |
| 3037 | | wip_decls: *WipDecls, |
| 3111 | wip_members: *WipMembers, |
| 3038 | 3112 | decl_node: Ast.Node.Index, |
| 3039 | 3113 | body_node: Ast.Node.Index, |
| 3040 | 3114 | fn_proto: Ast.full.FnProto, |
| ... | ... | @@ -3086,7 +3160,7 @@ fn fnDecl( |
| 3086 | 3160 | break :blk token_tags[maybe_inline_token] == .keyword_inline; |
| 3087 | 3161 | }; |
| 3088 | 3162 | 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); |
| 3090 | 3164 | |
| 3091 | 3165 | var params_scope = &fn_gz.base; |
| 3092 | 3166 | const is_var_args = is_var_args: { |
| ... | ... | @@ -3287,25 +3361,23 @@ fn fnDecl( |
| 3287 | 3361 | _ = try decl_gz.addBreak(.break_inline, block_inst, func_inst); |
| 3288 | 3362 | try decl_gz.setBlockBody(block_inst); |
| 3289 | 3363 | |
| 3290 | | try wip_decls.payload.ensureUnusedCapacity(gpa, 10); |
| 3291 | 3364 | { |
| 3292 | 3365 | const contents_hash = std.zig.hashSrc(tree.getNodeSource(decl_node)); |
| 3293 | 3366 | const casted = @bitCast([4]u32, contents_hash); |
| 3294 | | wip_decls.payload.appendSliceAssumeCapacity(&casted); |
| 3367 | wip_members.appendToDeclSlice(&casted); |
| 3295 | 3368 | } |
| 3296 | 3369 | { |
| 3297 | 3370 | const line_delta = decl_gz.decl_line - gz.decl_line; |
| 3298 | | wip_decls.payload.appendAssumeCapacity(line_delta); |
| 3371 | wip_members.appendToDecl(line_delta); |
| 3299 | 3372 | } |
| 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); |
| 3302 | 3375 | if (align_inst != .none) { |
| 3303 | | wip_decls.payload.appendAssumeCapacity(@enumToInt(align_inst)); |
| 3376 | wip_members.appendToDecl(@enumToInt(align_inst)); |
| 3304 | 3377 | } |
| 3305 | | |
| 3306 | 3378 | 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)); |
| 3309 | 3381 | } |
| 3310 | 3382 | } |
| 3311 | 3383 | |
| ... | ... | @@ -3313,7 +3385,7 @@ fn globalVarDecl( |
| 3313 | 3385 | astgen: *AstGen, |
| 3314 | 3386 | gz: *GenZir, |
| 3315 | 3387 | scope: *Scope, |
| 3316 | | wip_decls: *WipDecls, |
| 3388 | wip_members: *WipMembers, |
| 3317 | 3389 | node: Ast.Node.Index, |
| 3318 | 3390 | var_decl: Ast.full.VarDecl, |
| 3319 | 3391 | ) InnerError!void { |
| ... | ... | @@ -3359,7 +3431,7 @@ fn globalVarDecl( |
| 3359 | 3431 | break :inst try comptimeExpr(&block_scope, &block_scope.base, .{ .ty = .const_slice_u8_type }, var_decl.ast.section_node); |
| 3360 | 3432 | }; |
| 3361 | 3433 | 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); |
| 3363 | 3435 | |
| 3364 | 3436 | const is_threadlocal = if (var_decl.threadlocal_token) |tok| blk: { |
| 3365 | 3437 | if (!is_mutable) { |
| ... | ... | @@ -3437,24 +3509,23 @@ fn globalVarDecl( |
| 3437 | 3509 | _ = try block_scope.addBreak(.break_inline, block_inst, var_inst); |
| 3438 | 3510 | try block_scope.setBlockBody(block_inst); |
| 3439 | 3511 | |
| 3440 | | try wip_decls.payload.ensureUnusedCapacity(gpa, 10); |
| 3441 | 3512 | { |
| 3442 | 3513 | const contents_hash = std.zig.hashSrc(tree.getNodeSource(node)); |
| 3443 | 3514 | const casted = @bitCast([4]u32, contents_hash); |
| 3444 | | wip_decls.payload.appendSliceAssumeCapacity(&casted); |
| 3515 | wip_members.appendToDeclSlice(&casted); |
| 3445 | 3516 | } |
| 3446 | 3517 | { |
| 3447 | 3518 | const line_delta = block_scope.decl_line - gz.decl_line; |
| 3448 | | wip_decls.payload.appendAssumeCapacity(line_delta); |
| 3519 | wip_members.appendToDecl(line_delta); |
| 3449 | 3520 | } |
| 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); |
| 3452 | 3523 | if (align_inst != .none) { |
| 3453 | | wip_decls.payload.appendAssumeCapacity(@enumToInt(align_inst)); |
| 3524 | wip_members.appendToDecl(@enumToInt(align_inst)); |
| 3454 | 3525 | } |
| 3455 | 3526 | 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)); |
| 3458 | 3529 | } |
| 3459 | 3530 | } |
| 3460 | 3531 | |
| ... | ... | @@ -3462,7 +3533,7 @@ fn comptimeDecl( |
| 3462 | 3533 | astgen: *AstGen, |
| 3463 | 3534 | gz: *GenZir, |
| 3464 | 3535 | scope: *Scope, |
| 3465 | | wip_decls: *WipDecls, |
| 3536 | wip_members: *WipMembers, |
| 3466 | 3537 | node: Ast.Node.Index, |
| 3467 | 3538 | ) InnerError!void { |
| 3468 | 3539 | const gpa = astgen.gpa; |
| ... | ... | @@ -3473,7 +3544,7 @@ fn comptimeDecl( |
| 3473 | 3544 | // Up top so the ZIR instruction index marks the start range of this |
| 3474 | 3545 | // top-level declaration. |
| 3475 | 3546 | 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); |
| 3477 | 3548 | |
| 3478 | 3549 | var decl_block: GenZir = .{ |
| 3479 | 3550 | .force_comptime = true, |
| ... | ... | @@ -3491,25 +3562,24 @@ fn comptimeDecl( |
| 3491 | 3562 | } |
| 3492 | 3563 | try decl_block.setBlockBody(block_inst); |
| 3493 | 3564 | |
| 3494 | | try wip_decls.payload.ensureUnusedCapacity(gpa, 7); |
| 3495 | 3565 | { |
| 3496 | 3566 | const contents_hash = std.zig.hashSrc(tree.getNodeSource(node)); |
| 3497 | 3567 | const casted = @bitCast([4]u32, contents_hash); |
| 3498 | | wip_decls.payload.appendSliceAssumeCapacity(&casted); |
| 3568 | wip_members.appendToDeclSlice(&casted); |
| 3499 | 3569 | } |
| 3500 | 3570 | { |
| 3501 | 3571 | const line_delta = decl_block.decl_line - gz.decl_line; |
| 3502 | | wip_decls.payload.appendAssumeCapacity(line_delta); |
| 3572 | wip_members.appendToDecl(line_delta); |
| 3503 | 3573 | } |
| 3504 | | wip_decls.payload.appendAssumeCapacity(0); |
| 3505 | | wip_decls.payload.appendAssumeCapacity(block_inst); |
| 3574 | wip_members.appendToDecl(0); |
| 3575 | wip_members.appendToDecl(block_inst); |
| 3506 | 3576 | } |
| 3507 | 3577 | |
| 3508 | 3578 | fn usingnamespaceDecl( |
| 3509 | 3579 | astgen: *AstGen, |
| 3510 | 3580 | gz: *GenZir, |
| 3511 | 3581 | scope: *Scope, |
| 3512 | | wip_decls: *WipDecls, |
| 3582 | wip_members: *WipMembers, |
| 3513 | 3583 | node: Ast.Node.Index, |
| 3514 | 3584 | ) InnerError!void { |
| 3515 | 3585 | const gpa = astgen.gpa; |
| ... | ... | @@ -3526,7 +3596,7 @@ fn usingnamespaceDecl( |
| 3526 | 3596 | // Up top so the ZIR instruction index marks the start range of this |
| 3527 | 3597 | // top-level declaration. |
| 3528 | 3598 | 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); |
| 3530 | 3600 | |
| 3531 | 3601 | var decl_block: GenZir = .{ |
| 3532 | 3602 | .force_comptime = true, |
| ... | ... | @@ -3542,25 +3612,24 @@ fn usingnamespaceDecl( |
| 3542 | 3612 | _ = try decl_block.addBreak(.break_inline, block_inst, namespace_inst); |
| 3543 | 3613 | try decl_block.setBlockBody(block_inst); |
| 3544 | 3614 | |
| 3545 | | try wip_decls.payload.ensureUnusedCapacity(gpa, 7); |
| 3546 | 3615 | { |
| 3547 | 3616 | const contents_hash = std.zig.hashSrc(tree.getNodeSource(node)); |
| 3548 | 3617 | const casted = @bitCast([4]u32, contents_hash); |
| 3549 | | wip_decls.payload.appendSliceAssumeCapacity(&casted); |
| 3618 | wip_members.appendToDeclSlice(&casted); |
| 3550 | 3619 | } |
| 3551 | 3620 | { |
| 3552 | 3621 | const line_delta = decl_block.decl_line - gz.decl_line; |
| 3553 | | wip_decls.payload.appendAssumeCapacity(line_delta); |
| 3622 | wip_members.appendToDecl(line_delta); |
| 3554 | 3623 | } |
| 3555 | | wip_decls.payload.appendAssumeCapacity(0); |
| 3556 | | wip_decls.payload.appendAssumeCapacity(block_inst); |
| 3624 | wip_members.appendToDecl(0); |
| 3625 | wip_members.appendToDecl(block_inst); |
| 3557 | 3626 | } |
| 3558 | 3627 | |
| 3559 | 3628 | fn testDecl( |
| 3560 | 3629 | astgen: *AstGen, |
| 3561 | 3630 | gz: *GenZir, |
| 3562 | 3631 | scope: *Scope, |
| 3563 | | wip_decls: *WipDecls, |
| 3632 | wip_members: *WipMembers, |
| 3564 | 3633 | node: Ast.Node.Index, |
| 3565 | 3634 | ) InnerError!void { |
| 3566 | 3635 | const gpa = astgen.gpa; |
| ... | ... | @@ -3572,7 +3641,7 @@ fn testDecl( |
| 3572 | 3641 | // top-level declaration. |
| 3573 | 3642 | const block_inst = try gz.addBlock(.block_inline, node); |
| 3574 | 3643 | |
| 3575 | | try wip_decls.next(gpa, false, false, false, false); |
| 3644 | wip_members.nextDecl(false, false, false, false); |
| 3576 | 3645 | |
| 3577 | 3646 | var decl_block: GenZir = .{ |
| 3578 | 3647 | .force_comptime = true, |
| ... | ... | @@ -3643,18 +3712,17 @@ fn testDecl( |
| 3643 | 3712 | _ = try decl_block.addBreak(.break_inline, block_inst, func_inst); |
| 3644 | 3713 | try decl_block.setBlockBody(block_inst); |
| 3645 | 3714 | |
| 3646 | | try wip_decls.payload.ensureUnusedCapacity(gpa, 7); |
| 3647 | 3715 | { |
| 3648 | 3716 | const contents_hash = std.zig.hashSrc(tree.getNodeSource(node)); |
| 3649 | 3717 | const casted = @bitCast([4]u32, contents_hash); |
| 3650 | | wip_decls.payload.appendSliceAssumeCapacity(&casted); |
| 3718 | wip_members.appendToDeclSlice(&casted); |
| 3651 | 3719 | } |
| 3652 | 3720 | { |
| 3653 | 3721 | const line_delta = decl_block.decl_line - gz.decl_line; |
| 3654 | | wip_decls.payload.appendAssumeCapacity(line_delta); |
| 3722 | wip_members.appendToDecl(line_delta); |
| 3655 | 3723 | } |
| 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); |
| 3658 | 3726 | } |
| 3659 | 3727 | |
| 3660 | 3728 | fn structDeclInner( |
| ... | ... | @@ -3705,25 +3773,15 @@ fn structDeclInner( |
| 3705 | 3773 | }; |
| 3706 | 3774 | defer block_scope.instructions.deinit(gpa); |
| 3707 | 3775 | |
| 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); |
| 3717 | 3778 | |
| 3718 | 3779 | 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); |
| 3723 | 3783 | |
| 3724 | 3784 | var known_has_bits = false; |
| 3725 | | var cur_bit_bag: u32 = 0; |
| 3726 | | var field_index: usize = 0; |
| 3727 | 3785 | for (container_decl.ast.members) |member_node| { |
| 3728 | 3786 | const member = switch (node_tags[member_node]) { |
| 3729 | 3787 | .container_field_init => tree.containerFieldInit(member_node), |
| ... | ... | @@ -3736,14 +3794,14 @@ fn structDeclInner( |
| 3736 | 3794 | switch (node_tags[fn_proto]) { |
| 3737 | 3795 | .fn_proto_simple => { |
| 3738 | 3796 | 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) { |
| 3740 | 3798 | error.OutOfMemory => return error.OutOfMemory, |
| 3741 | 3799 | error.AnalysisFail => {}, |
| 3742 | 3800 | }; |
| 3743 | 3801 | continue; |
| 3744 | 3802 | }, |
| 3745 | 3803 | .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) { |
| 3747 | 3805 | error.OutOfMemory => return error.OutOfMemory, |
| 3748 | 3806 | error.AnalysisFail => {}, |
| 3749 | 3807 | }; |
| ... | ... | @@ -3751,14 +3809,14 @@ fn structDeclInner( |
| 3751 | 3809 | }, |
| 3752 | 3810 | .fn_proto_one => { |
| 3753 | 3811 | 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) { |
| 3755 | 3813 | error.OutOfMemory => return error.OutOfMemory, |
| 3756 | 3814 | error.AnalysisFail => {}, |
| 3757 | 3815 | }; |
| 3758 | 3816 | continue; |
| 3759 | 3817 | }, |
| 3760 | 3818 | .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) { |
| 3762 | 3820 | error.OutOfMemory => return error.OutOfMemory, |
| 3763 | 3821 | error.AnalysisFail => {}, |
| 3764 | 3822 | }; |
| ... | ... | @@ -3769,14 +3827,14 @@ fn structDeclInner( |
| 3769 | 3827 | }, |
| 3770 | 3828 | .fn_proto_simple => { |
| 3771 | 3829 | 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) { |
| 3773 | 3831 | error.OutOfMemory => return error.OutOfMemory, |
| 3774 | 3832 | error.AnalysisFail => {}, |
| 3775 | 3833 | }; |
| 3776 | 3834 | continue; |
| 3777 | 3835 | }, |
| 3778 | 3836 | .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) { |
| 3780 | 3838 | error.OutOfMemory => return error.OutOfMemory, |
| 3781 | 3839 | error.AnalysisFail => {}, |
| 3782 | 3840 | }; |
| ... | ... | @@ -3784,14 +3842,14 @@ fn structDeclInner( |
| 3784 | 3842 | }, |
| 3785 | 3843 | .fn_proto_one => { |
| 3786 | 3844 | 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) { |
| 3788 | 3846 | error.OutOfMemory => return error.OutOfMemory, |
| 3789 | 3847 | error.AnalysisFail => {}, |
| 3790 | 3848 | }; |
| 3791 | 3849 | continue; |
| 3792 | 3850 | }, |
| 3793 | 3851 | .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) { |
| 3795 | 3853 | error.OutOfMemory => return error.OutOfMemory, |
| 3796 | 3854 | error.AnalysisFail => {}, |
| 3797 | 3855 | }; |
| ... | ... | @@ -3799,28 +3857,28 @@ fn structDeclInner( |
| 3799 | 3857 | }, |
| 3800 | 3858 | |
| 3801 | 3859 | .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) { |
| 3803 | 3861 | error.OutOfMemory => return error.OutOfMemory, |
| 3804 | 3862 | error.AnalysisFail => {}, |
| 3805 | 3863 | }; |
| 3806 | 3864 | continue; |
| 3807 | 3865 | }, |
| 3808 | 3866 | .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) { |
| 3810 | 3868 | error.OutOfMemory => return error.OutOfMemory, |
| 3811 | 3869 | error.AnalysisFail => {}, |
| 3812 | 3870 | }; |
| 3813 | 3871 | continue; |
| 3814 | 3872 | }, |
| 3815 | 3873 | .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) { |
| 3817 | 3875 | error.OutOfMemory => return error.OutOfMemory, |
| 3818 | 3876 | error.AnalysisFail => {}, |
| 3819 | 3877 | }; |
| 3820 | 3878 | continue; |
| 3821 | 3879 | }, |
| 3822 | 3880 | .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) { |
| 3824 | 3882 | error.OutOfMemory => return error.OutOfMemory, |
| 3825 | 3883 | error.AnalysisFail => {}, |
| 3826 | 3884 | }; |
| ... | ... | @@ -3828,21 +3886,21 @@ fn structDeclInner( |
| 3828 | 3886 | }, |
| 3829 | 3887 | |
| 3830 | 3888 | .@"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) { |
| 3832 | 3890 | error.OutOfMemory => return error.OutOfMemory, |
| 3833 | 3891 | error.AnalysisFail => {}, |
| 3834 | 3892 | }; |
| 3835 | 3893 | continue; |
| 3836 | 3894 | }, |
| 3837 | 3895 | .@"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) { |
| 3839 | 3897 | error.OutOfMemory => return error.OutOfMemory, |
| 3840 | 3898 | error.AnalysisFail => {}, |
| 3841 | 3899 | }; |
| 3842 | 3900 | continue; |
| 3843 | 3901 | }, |
| 3844 | 3902 | .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) { |
| 3846 | 3904 | error.OutOfMemory => return error.OutOfMemory, |
| 3847 | 3905 | error.AnalysisFail => {}, |
| 3848 | 3906 | }; |
| ... | ... | @@ -3850,14 +3908,9 @@ fn structDeclInner( |
| 3850 | 3908 | }, |
| 3851 | 3909 | else => unreachable, |
| 3852 | 3910 | }; |
| 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); |
| 3858 | 3911 | |
| 3859 | 3912 | const field_name = try astgen.identAsString(member.ast.name_token); |
| 3860 | | fields_data.appendAssumeCapacity(field_name); |
| 3913 | wip_members.appendToField(field_name); |
| 3861 | 3914 | |
| 3862 | 3915 | if (member.ast.type_expr == 0) { |
| 3863 | 3916 | return astgen.failTok(member.ast.name_token, "struct field missing type", .{}); |
| ... | ... | @@ -3867,7 +3920,7 @@ fn structDeclInner( |
| 3867 | 3920 | .none |
| 3868 | 3921 | else |
| 3869 | 3922 | try typeExpr(&block_scope, &namespace.base, member.ast.type_expr); |
| 3870 | | fields_data.appendAssumeCapacity(@enumToInt(field_type)); |
| 3923 | wip_members.appendToField(@enumToInt(field_type)); |
| 3871 | 3924 | |
| 3872 | 3925 | known_has_bits = known_has_bits or nodeImpliesRuntimeBits(tree, member.ast.type_expr); |
| 3873 | 3926 | |
| ... | ... | @@ -3875,39 +3928,22 @@ fn structDeclInner( |
| 3875 | 3928 | const have_value = member.ast.value_expr != 0; |
| 3876 | 3929 | const is_comptime = member.comptime_token != null; |
| 3877 | 3930 | 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 }); |
| 3883 | 3932 | |
| 3884 | 3933 | if (have_align) { |
| 3885 | 3934 | 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)); |
| 3887 | 3936 | } |
| 3888 | 3937 | if (have_value) { |
| 3889 | 3938 | const rl: ResultLoc = if (field_type == .none) .none else .{ .ty = field_type }; |
| 3890 | 3939 | |
| 3891 | 3940 | 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)); |
| 3893 | 3942 | } else if (member.comptime_token) |comptime_token| { |
| 3894 | 3943 | return astgen.failTok(comptime_token, "comptime field without default initialization value", .{}); |
| 3895 | 3944 | } |
| 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 | | } |
| 3910 | 3945 | } |
| 3946 | assert(wip_members.decl_index == decl_count and wip_members.field_index == field_count); |
| 3911 | 3947 | |
| 3912 | 3948 | if (block_scope.instructions.items.len != 0) { |
| 3913 | 3949 | _ = try block_scope.addBreak(.break_inline, decl_inst, .void_value); |
| ... | ... | @@ -3917,36 +3953,18 @@ fn structDeclInner( |
| 3917 | 3953 | .src_node = node, |
| 3918 | 3954 | .layout = layout, |
| 3919 | 3955 | .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, |
| 3922 | 3958 | .known_has_bits = known_has_bits, |
| 3923 | 3959 | }); |
| 3924 | 3960 | |
| 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); |
| 3943 | 3966 | 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); |
| 3950 | 3968 | |
| 3951 | 3969 | return indexToRef(decl_inst); |
| 3952 | 3970 | } |
| ... | ... | @@ -3989,29 +4007,19 @@ fn unionDeclInner( |
| 3989 | 4007 | }; |
| 3990 | 4008 | defer block_scope.instructions.deinit(gpa); |
| 3991 | 4009 | |
| 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); |
| 3993 | 4012 | |
| 3994 | 4013 | const arg_inst: Zir.Inst.Ref = if (arg_node != 0) |
| 3995 | 4014 | try typeExpr(&block_scope, &namespace.base, arg_node) |
| 3996 | 4015 | else |
| 3997 | 4016 | .none; |
| 3998 | 4017 | |
| 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 | | |
| 4007 | 4018 | 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); |
| 4012 | 4022 | |
| 4013 | | var cur_bit_bag: u32 = 0; |
| 4014 | | var field_index: usize = 0; |
| 4015 | 4023 | for (members) |member_node| { |
| 4016 | 4024 | const member = switch (node_tags[member_node]) { |
| 4017 | 4025 | .container_field_init => tree.containerFieldInit(member_node), |
| ... | ... | @@ -4024,14 +4032,14 @@ fn unionDeclInner( |
| 4024 | 4032 | switch (node_tags[fn_proto]) { |
| 4025 | 4033 | .fn_proto_simple => { |
| 4026 | 4034 | 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) { |
| 4028 | 4036 | error.OutOfMemory => return error.OutOfMemory, |
| 4029 | 4037 | error.AnalysisFail => {}, |
| 4030 | 4038 | }; |
| 4031 | 4039 | continue; |
| 4032 | 4040 | }, |
| 4033 | 4041 | .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) { |
| 4035 | 4043 | error.OutOfMemory => return error.OutOfMemory, |
| 4036 | 4044 | error.AnalysisFail => {}, |
| 4037 | 4045 | }; |
| ... | ... | @@ -4039,14 +4047,14 @@ fn unionDeclInner( |
| 4039 | 4047 | }, |
| 4040 | 4048 | .fn_proto_one => { |
| 4041 | 4049 | 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) { |
| 4043 | 4051 | error.OutOfMemory => return error.OutOfMemory, |
| 4044 | 4052 | error.AnalysisFail => {}, |
| 4045 | 4053 | }; |
| 4046 | 4054 | continue; |
| 4047 | 4055 | }, |
| 4048 | 4056 | .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) { |
| 4050 | 4058 | error.OutOfMemory => return error.OutOfMemory, |
| 4051 | 4059 | error.AnalysisFail => {}, |
| 4052 | 4060 | }; |
| ... | ... | @@ -4057,14 +4065,14 @@ fn unionDeclInner( |
| 4057 | 4065 | }, |
| 4058 | 4066 | .fn_proto_simple => { |
| 4059 | 4067 | 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) { |
| 4061 | 4069 | error.OutOfMemory => return error.OutOfMemory, |
| 4062 | 4070 | error.AnalysisFail => {}, |
| 4063 | 4071 | }; |
| 4064 | 4072 | continue; |
| 4065 | 4073 | }, |
| 4066 | 4074 | .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) { |
| 4068 | 4076 | error.OutOfMemory => return error.OutOfMemory, |
| 4069 | 4077 | error.AnalysisFail => {}, |
| 4070 | 4078 | }; |
| ... | ... | @@ -4072,14 +4080,14 @@ fn unionDeclInner( |
| 4072 | 4080 | }, |
| 4073 | 4081 | .fn_proto_one => { |
| 4074 | 4082 | 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) { |
| 4076 | 4084 | error.OutOfMemory => return error.OutOfMemory, |
| 4077 | 4085 | error.AnalysisFail => {}, |
| 4078 | 4086 | }; |
| 4079 | 4087 | continue; |
| 4080 | 4088 | }, |
| 4081 | 4089 | .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) { |
| 4083 | 4091 | error.OutOfMemory => return error.OutOfMemory, |
| 4084 | 4092 | error.AnalysisFail => {}, |
| 4085 | 4093 | }; |
| ... | ... | @@ -4087,28 +4095,28 @@ fn unionDeclInner( |
| 4087 | 4095 | }, |
| 4088 | 4096 | |
| 4089 | 4097 | .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) { |
| 4091 | 4099 | error.OutOfMemory => return error.OutOfMemory, |
| 4092 | 4100 | error.AnalysisFail => {}, |
| 4093 | 4101 | }; |
| 4094 | 4102 | continue; |
| 4095 | 4103 | }, |
| 4096 | 4104 | .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) { |
| 4098 | 4106 | error.OutOfMemory => return error.OutOfMemory, |
| 4099 | 4107 | error.AnalysisFail => {}, |
| 4100 | 4108 | }; |
| 4101 | 4109 | continue; |
| 4102 | 4110 | }, |
| 4103 | 4111 | .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) { |
| 4105 | 4113 | error.OutOfMemory => return error.OutOfMemory, |
| 4106 | 4114 | error.AnalysisFail => {}, |
| 4107 | 4115 | }; |
| 4108 | 4116 | continue; |
| 4109 | 4117 | }, |
| 4110 | 4118 | .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) { |
| 4112 | 4120 | error.OutOfMemory => return error.OutOfMemory, |
| 4113 | 4121 | error.AnalysisFail => {}, |
| 4114 | 4122 | }; |
| ... | ... | @@ -4116,21 +4124,21 @@ fn unionDeclInner( |
| 4116 | 4124 | }, |
| 4117 | 4125 | |
| 4118 | 4126 | .@"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) { |
| 4120 | 4128 | error.OutOfMemory => return error.OutOfMemory, |
| 4121 | 4129 | error.AnalysisFail => {}, |
| 4122 | 4130 | }; |
| 4123 | 4131 | continue; |
| 4124 | 4132 | }, |
| 4125 | 4133 | .@"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) { |
| 4127 | 4135 | error.OutOfMemory => return error.OutOfMemory, |
| 4128 | 4136 | error.AnalysisFail => {}, |
| 4129 | 4137 | }; |
| 4130 | 4138 | continue; |
| 4131 | 4139 | }, |
| 4132 | 4140 | .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) { |
| 4134 | 4142 | error.OutOfMemory => return error.OutOfMemory, |
| 4135 | 4143 | error.AnalysisFail => {}, |
| 4136 | 4144 | }; |
| ... | ... | @@ -4138,40 +4146,31 @@ fn unionDeclInner( |
| 4138 | 4146 | }, |
| 4139 | 4147 | else => unreachable, |
| 4140 | 4148 | }; |
| 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 | | } |
| 4145 | 4149 | if (member.comptime_token) |comptime_token| { |
| 4146 | 4150 | return astgen.failTok(comptime_token, "union fields cannot be marked comptime", .{}); |
| 4147 | 4151 | } |
| 4148 | | try fields_data.ensureUnusedCapacity(gpa, 4); |
| 4149 | 4152 | |
| 4150 | 4153 | const field_name = try astgen.identAsString(member.ast.name_token); |
| 4151 | | fields_data.appendAssumeCapacity(field_name); |
| 4154 | wip_members.appendToField(field_name); |
| 4152 | 4155 | |
| 4153 | 4156 | const have_type = member.ast.type_expr != 0; |
| 4154 | 4157 | const have_align = member.ast.align_expr != 0; |
| 4155 | 4158 | const have_value = member.ast.value_expr != 0; |
| 4156 | 4159 | 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 }); |
| 4162 | 4161 | |
| 4163 | 4162 | if (have_type) { |
| 4164 | 4163 | const field_type: Zir.Inst.Ref = if (node_tags[member.ast.type_expr] == .@"anytype") |
| 4165 | 4164 | .none |
| 4166 | 4165 | else |
| 4167 | 4166 | try typeExpr(&block_scope, &namespace.base, member.ast.type_expr); |
| 4168 | | fields_data.appendAssumeCapacity(@enumToInt(field_type)); |
| 4167 | wip_members.appendToField(@enumToInt(field_type)); |
| 4169 | 4168 | } else if (arg_inst == .none and !have_auto_enum) { |
| 4170 | 4169 | return astgen.failNode(member_node, "union field missing type", .{}); |
| 4171 | 4170 | } |
| 4172 | 4171 | if (have_align) { |
| 4173 | 4172 | 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)); |
| 4175 | 4174 | } |
| 4176 | 4175 | if (have_value) { |
| 4177 | 4176 | if (arg_inst == .none) { |
| ... | ... | @@ -4203,26 +4202,13 @@ fn unionDeclInner( |
| 4203 | 4202 | ); |
| 4204 | 4203 | } |
| 4205 | 4204 | 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)); |
| 4207 | 4206 | } |
| 4208 | | |
| 4209 | | field_index += 1; |
| 4210 | 4207 | } |
| 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) { |
| 4212 | 4210 | return astgen.failNode(node, "union declarations must have at least one tag", .{}); |
| 4213 | 4211 | } |
| 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 | | } |
| 4226 | 4212 | |
| 4227 | 4213 | if (block_scope.instructions.items.len != 0) { |
| 4228 | 4214 | _ = try block_scope.addBreak(.break_inline, decl_inst, .void_value); |
| ... | ... | @@ -4233,34 +4219,18 @@ fn unionDeclInner( |
| 4233 | 4219 | .layout = layout, |
| 4234 | 4220 | .tag_type = arg_inst, |
| 4235 | 4221 | .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, |
| 4238 | 4224 | .auto_enum_tag = have_auto_enum, |
| 4239 | 4225 | }); |
| 4240 | 4226 | |
| 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); |
| 4259 | 4232 | 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); |
| 4264 | 4234 | |
| 4265 | 4235 | return indexToRef(decl_inst); |
| 4266 | 4236 | } |
| ... | ... | @@ -4434,27 +4404,18 @@ fn containerDecl( |
| 4434 | 4404 | }; |
| 4435 | 4405 | defer block_scope.instructions.deinit(gpa); |
| 4436 | 4406 | |
| 4437 | | try astgen.scanDecls(&namespace, container_decl.ast.members); |
| 4407 | _ = try astgen.scanDecls(&namespace, container_decl.ast.members); |
| 4438 | 4408 | |
| 4439 | 4409 | const arg_inst: Zir.Inst.Ref = if (container_decl.ast.arg != 0) |
| 4440 | 4410 | try comptimeExpr(&block_scope, &namespace.base, .{ .ty = .type_type }, container_decl.ast.arg) |
| 4441 | 4411 | else |
| 4442 | 4412 | .none; |
| 4443 | 4413 | |
| 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); |
| 4455 | 4418 | |
| 4456 | | var cur_bit_bag: u32 = 0; |
| 4457 | | var field_index: usize = 0; |
| 4458 | 4419 | for (container_decl.ast.members) |member_node| { |
| 4459 | 4420 | if (member_node == counts.nonexhaustive_node) |
| 4460 | 4421 | continue; |
| ... | ... | @@ -4469,14 +4430,14 @@ fn containerDecl( |
| 4469 | 4430 | switch (node_tags[fn_proto]) { |
| 4470 | 4431 | .fn_proto_simple => { |
| 4471 | 4432 | 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) { |
| 4473 | 4434 | error.OutOfMemory => return error.OutOfMemory, |
| 4474 | 4435 | error.AnalysisFail => {}, |
| 4475 | 4436 | }; |
| 4476 | 4437 | continue; |
| 4477 | 4438 | }, |
| 4478 | 4439 | .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) { |
| 4480 | 4441 | error.OutOfMemory => return error.OutOfMemory, |
| 4481 | 4442 | error.AnalysisFail => {}, |
| 4482 | 4443 | }; |
| ... | ... | @@ -4484,14 +4445,14 @@ fn containerDecl( |
| 4484 | 4445 | }, |
| 4485 | 4446 | .fn_proto_one => { |
| 4486 | 4447 | 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) { |
| 4488 | 4449 | error.OutOfMemory => return error.OutOfMemory, |
| 4489 | 4450 | error.AnalysisFail => {}, |
| 4490 | 4451 | }; |
| 4491 | 4452 | continue; |
| 4492 | 4453 | }, |
| 4493 | 4454 | .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) { |
| 4495 | 4456 | error.OutOfMemory => return error.OutOfMemory, |
| 4496 | 4457 | error.AnalysisFail => {}, |
| 4497 | 4458 | }; |
| ... | ... | @@ -4502,14 +4463,14 @@ fn containerDecl( |
| 4502 | 4463 | }, |
| 4503 | 4464 | .fn_proto_simple => { |
| 4504 | 4465 | 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) { |
| 4506 | 4467 | error.OutOfMemory => return error.OutOfMemory, |
| 4507 | 4468 | error.AnalysisFail => {}, |
| 4508 | 4469 | }; |
| 4509 | 4470 | continue; |
| 4510 | 4471 | }, |
| 4511 | 4472 | .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) { |
| 4513 | 4474 | error.OutOfMemory => return error.OutOfMemory, |
| 4514 | 4475 | error.AnalysisFail => {}, |
| 4515 | 4476 | }; |
| ... | ... | @@ -4517,14 +4478,14 @@ fn containerDecl( |
| 4517 | 4478 | }, |
| 4518 | 4479 | .fn_proto_one => { |
| 4519 | 4480 | 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) { |
| 4521 | 4482 | error.OutOfMemory => return error.OutOfMemory, |
| 4522 | 4483 | error.AnalysisFail => {}, |
| 4523 | 4484 | }; |
| 4524 | 4485 | continue; |
| 4525 | 4486 | }, |
| 4526 | 4487 | .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) { |
| 4528 | 4489 | error.OutOfMemory => return error.OutOfMemory, |
| 4529 | 4490 | error.AnalysisFail => {}, |
| 4530 | 4491 | }; |
| ... | ... | @@ -4532,28 +4493,28 @@ fn containerDecl( |
| 4532 | 4493 | }, |
| 4533 | 4494 | |
| 4534 | 4495 | .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) { |
| 4536 | 4497 | error.OutOfMemory => return error.OutOfMemory, |
| 4537 | 4498 | error.AnalysisFail => {}, |
| 4538 | 4499 | }; |
| 4539 | 4500 | continue; |
| 4540 | 4501 | }, |
| 4541 | 4502 | .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) { |
| 4543 | 4504 | error.OutOfMemory => return error.OutOfMemory, |
| 4544 | 4505 | error.AnalysisFail => {}, |
| 4545 | 4506 | }; |
| 4546 | 4507 | continue; |
| 4547 | 4508 | }, |
| 4548 | 4509 | .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) { |
| 4550 | 4511 | error.OutOfMemory => return error.OutOfMemory, |
| 4551 | 4512 | error.AnalysisFail => {}, |
| 4552 | 4513 | }; |
| 4553 | 4514 | continue; |
| 4554 | 4515 | }, |
| 4555 | 4516 | .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) { |
| 4557 | 4518 | error.OutOfMemory => return error.OutOfMemory, |
| 4558 | 4519 | error.AnalysisFail => {}, |
| 4559 | 4520 | }; |
| ... | ... | @@ -4561,21 +4522,21 @@ fn containerDecl( |
| 4561 | 4522 | }, |
| 4562 | 4523 | |
| 4563 | 4524 | .@"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) { |
| 4565 | 4526 | error.OutOfMemory => return error.OutOfMemory, |
| 4566 | 4527 | error.AnalysisFail => {}, |
| 4567 | 4528 | }; |
| 4568 | 4529 | continue; |
| 4569 | 4530 | }, |
| 4570 | 4531 | .@"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) { |
| 4572 | 4533 | error.OutOfMemory => return error.OutOfMemory, |
| 4573 | 4534 | error.AnalysisFail => {}, |
| 4574 | 4535 | }; |
| 4575 | 4536 | continue; |
| 4576 | 4537 | }, |
| 4577 | 4538 | .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) { |
| 4579 | 4540 | error.OutOfMemory => return error.OutOfMemory, |
| 4580 | 4541 | error.AnalysisFail => {}, |
| 4581 | 4542 | }; |
| ... | ... | @@ -4583,20 +4544,15 @@ fn containerDecl( |
| 4583 | 4544 | }, |
| 4584 | 4545 | else => unreachable, |
| 4585 | 4546 | }; |
| 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 | | } |
| 4590 | 4547 | assert(member.comptime_token == null); |
| 4591 | 4548 | assert(member.ast.type_expr == 0); |
| 4592 | 4549 | assert(member.ast.align_expr == 0); |
| 4593 | 4550 | |
| 4594 | 4551 | const field_name = try astgen.identAsString(member.ast.name_token); |
| 4595 | | fields_data.appendAssumeCapacity(field_name); |
| 4552 | wip_members.appendToField(field_name); |
| 4596 | 4553 | |
| 4597 | 4554 | 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}); |
| 4600 | 4556 | |
| 4601 | 4557 | if (have_value) { |
| 4602 | 4558 | if (arg_inst == .none) { |
| ... | ... | @@ -4614,23 +4570,10 @@ fn containerDecl( |
| 4614 | 4570 | ); |
| 4615 | 4571 | } |
| 4616 | 4572 | 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)); |
| 4632 | 4574 | } |
| 4633 | 4575 | } |
| 4576 | assert(wip_members.decl_index == counts.decls and wip_members.field_index == counts.total_fields); |
| 4634 | 4577 | |
| 4635 | 4578 | if (block_scope.instructions.items.len != 0) { |
| 4636 | 4579 | _ = try block_scope.addBreak(.break_inline, decl_inst, .void_value); |
| ... | ... | @@ -4641,32 +4584,17 @@ fn containerDecl( |
| 4641 | 4584 | .nonexhaustive = nonexhaustive, |
| 4642 | 4585 | .tag_type = arg_inst, |
| 4643 | 4586 | .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), |
| 4646 | 4589 | }); |
| 4647 | 4590 | |
| 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); |
| 4666 | 4596 | 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); |
| 4670 | 4598 | |
| 4671 | 4599 | return rvalue(gz, rl, indexToRef(decl_inst), node); |
| 4672 | 4600 | }, |
| ... | ... | @@ -4683,10 +4611,10 @@ fn containerDecl( |
| 4683 | 4611 | }; |
| 4684 | 4612 | defer namespace.deinit(gpa); |
| 4685 | 4613 | |
| 4686 | | try astgen.scanDecls(&namespace, container_decl.ast.members); |
| 4614 | const decl_count = try astgen.scanDecls(&namespace, container_decl.ast.members); |
| 4687 | 4615 | |
| 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); |
| 4690 | 4618 | |
| 4691 | 4619 | for (container_decl.ast.members) |member_node| { |
| 4692 | 4620 | switch (node_tags[member_node]) { |
| ... | ... | @@ -4698,14 +4626,14 @@ fn containerDecl( |
| 4698 | 4626 | switch (node_tags[fn_proto]) { |
| 4699 | 4627 | .fn_proto_simple => { |
| 4700 | 4628 | 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) { |
| 4702 | 4630 | error.OutOfMemory => return error.OutOfMemory, |
| 4703 | 4631 | error.AnalysisFail => {}, |
| 4704 | 4632 | }; |
| 4705 | 4633 | continue; |
| 4706 | 4634 | }, |
| 4707 | 4635 | .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) { |
| 4709 | 4637 | error.OutOfMemory => return error.OutOfMemory, |
| 4710 | 4638 | error.AnalysisFail => {}, |
| 4711 | 4639 | }; |
| ... | ... | @@ -4713,14 +4641,14 @@ fn containerDecl( |
| 4713 | 4641 | }, |
| 4714 | 4642 | .fn_proto_one => { |
| 4715 | 4643 | 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) { |
| 4717 | 4645 | error.OutOfMemory => return error.OutOfMemory, |
| 4718 | 4646 | error.AnalysisFail => {}, |
| 4719 | 4647 | }; |
| 4720 | 4648 | continue; |
| 4721 | 4649 | }, |
| 4722 | 4650 | .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) { |
| 4724 | 4652 | error.OutOfMemory => return error.OutOfMemory, |
| 4725 | 4653 | error.AnalysisFail => {}, |
| 4726 | 4654 | }; |
| ... | ... | @@ -4731,14 +4659,14 @@ fn containerDecl( |
| 4731 | 4659 | }, |
| 4732 | 4660 | .fn_proto_simple => { |
| 4733 | 4661 | 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) { |
| 4735 | 4663 | error.OutOfMemory => return error.OutOfMemory, |
| 4736 | 4664 | error.AnalysisFail => {}, |
| 4737 | 4665 | }; |
| 4738 | 4666 | continue; |
| 4739 | 4667 | }, |
| 4740 | 4668 | .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) { |
| 4742 | 4670 | error.OutOfMemory => return error.OutOfMemory, |
| 4743 | 4671 | error.AnalysisFail => {}, |
| 4744 | 4672 | }; |
| ... | ... | @@ -4746,14 +4674,14 @@ fn containerDecl( |
| 4746 | 4674 | }, |
| 4747 | 4675 | .fn_proto_one => { |
| 4748 | 4676 | 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) { |
| 4750 | 4678 | error.OutOfMemory => return error.OutOfMemory, |
| 4751 | 4679 | error.AnalysisFail => {}, |
| 4752 | 4680 | }; |
| 4753 | 4681 | continue; |
| 4754 | 4682 | }, |
| 4755 | 4683 | .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) { |
| 4757 | 4685 | error.OutOfMemory => return error.OutOfMemory, |
| 4758 | 4686 | error.AnalysisFail => {}, |
| 4759 | 4687 | }; |
| ... | ... | @@ -4761,28 +4689,28 @@ fn containerDecl( |
| 4761 | 4689 | }, |
| 4762 | 4690 | |
| 4763 | 4691 | .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) { |
| 4765 | 4693 | error.OutOfMemory => return error.OutOfMemory, |
| 4766 | 4694 | error.AnalysisFail => {}, |
| 4767 | 4695 | }; |
| 4768 | 4696 | continue; |
| 4769 | 4697 | }, |
| 4770 | 4698 | .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) { |
| 4772 | 4700 | error.OutOfMemory => return error.OutOfMemory, |
| 4773 | 4701 | error.AnalysisFail => {}, |
| 4774 | 4702 | }; |
| 4775 | 4703 | continue; |
| 4776 | 4704 | }, |
| 4777 | 4705 | .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) { |
| 4779 | 4707 | error.OutOfMemory => return error.OutOfMemory, |
| 4780 | 4708 | error.AnalysisFail => {}, |
| 4781 | 4709 | }; |
| 4782 | 4710 | continue; |
| 4783 | 4711 | }, |
| 4784 | 4712 | .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) { |
| 4786 | 4714 | error.OutOfMemory => return error.OutOfMemory, |
| 4787 | 4715 | error.AnalysisFail => {}, |
| 4788 | 4716 | }; |
| ... | ... | @@ -4790,21 +4718,21 @@ fn containerDecl( |
| 4790 | 4718 | }, |
| 4791 | 4719 | |
| 4792 | 4720 | .@"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) { |
| 4794 | 4722 | error.OutOfMemory => return error.OutOfMemory, |
| 4795 | 4723 | error.AnalysisFail => {}, |
| 4796 | 4724 | }; |
| 4797 | 4725 | continue; |
| 4798 | 4726 | }, |
| 4799 | 4727 | .@"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) { |
| 4801 | 4729 | error.OutOfMemory => return error.OutOfMemory, |
| 4802 | 4730 | error.AnalysisFail => {}, |
| 4803 | 4731 | }; |
| 4804 | 4732 | continue; |
| 4805 | 4733 | }, |
| 4806 | 4734 | .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) { |
| 4808 | 4736 | error.OutOfMemory => return error.OutOfMemory, |
| 4809 | 4737 | error.AnalysisFail => {}, |
| 4810 | 4738 | }; |
| ... | ... | @@ -4813,31 +4741,17 @@ fn containerDecl( |
| 4813 | 4741 | else => unreachable, |
| 4814 | 4742 | } |
| 4815 | 4743 | } |
| 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); |
| 4822 | 4745 | |
| 4823 | 4746 | try gz.setOpaque(decl_inst, .{ |
| 4824 | 4747 | .src_node = node, |
| 4825 | | .decls_len = @intCast(u32, wip_decls.decl_index), |
| 4748 | .decls_len = decl_count, |
| 4826 | 4749 | }); |
| 4827 | 4750 | |
| 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); |
| 4841 | 4755 | |
| 4842 | 4756 | return rvalue(gz, rl, indexToRef(decl_inst), node); |
| 4843 | 4757 | }, |
| ... | ... | @@ -10436,12 +10350,13 @@ fn advanceSourceCursor(astgen: *AstGen, source: []const u8, end: usize) void { |
| 10436 | 10350 | astgen.source_column = column; |
| 10437 | 10351 | } |
| 10438 | 10352 | |
| 10439 | | fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast.Node.Index) !void { |
| 10353 | fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast.Node.Index) !u32 { |
| 10440 | 10354 | const gpa = astgen.gpa; |
| 10441 | 10355 | const tree = astgen.tree; |
| 10442 | 10356 | const node_tags = tree.nodes.items(.tag); |
| 10443 | 10357 | const main_tokens = tree.nodes.items(.main_token); |
| 10444 | 10358 | const token_tags = tree.tokens.items(.tag); |
| 10359 | var decl_count: u32 = 0; |
| 10445 | 10360 | for (members) |member_node| { |
| 10446 | 10361 | const name_token = switch (node_tags[member_node]) { |
| 10447 | 10362 | .fn_proto_simple, |
| ... | ... | @@ -10452,9 +10367,13 @@ fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast. |
| 10452 | 10367 | .local_var_decl, |
| 10453 | 10368 | .simple_var_decl, |
| 10454 | 10369 | .aligned_var_decl, |
| 10455 | | => main_tokens[member_node] + 1, |
| 10370 | => blk: { |
| 10371 | decl_count += 1; |
| 10372 | break :blk main_tokens[member_node] + 1; |
| 10373 | }, |
| 10456 | 10374 | |
| 10457 | 10375 | .fn_decl => blk: { |
| 10376 | decl_count += 1; |
| 10458 | 10377 | const ident = main_tokens[member_node] + 1; |
| 10459 | 10378 | if (token_tags[ident] != .identifier) { |
| 10460 | 10379 | switch (astgen.failNode(member_node, "missing function name", .{})) { |
| ... | ... | @@ -10465,6 +10384,11 @@ fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast. |
| 10465 | 10384 | break :blk ident; |
| 10466 | 10385 | }, |
| 10467 | 10386 | |
| 10387 | .@"comptime", .@"usingnamespace", .test_decl => { |
| 10388 | decl_count += 1; |
| 10389 | continue; |
| 10390 | }, |
| 10391 | |
| 10468 | 10392 | else => continue, |
| 10469 | 10393 | }; |
| 10470 | 10394 | |
| ... | ... | @@ -10498,4 +10422,5 @@ fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast. |
| 10498 | 10422 | } |
| 10499 | 10423 | gop.value_ptr.* = member_node; |
| 10500 | 10424 | } |
| 10425 | return decl_count; |
| 10501 | 10426 | } |