| ... | @@ -3080,9 +3080,9 @@ const WipMembers = struct { | ... | @@ -3080,9 +3080,9 @@ const WipMembers = struct { |
| 3080 | /// struct, union, enum, and opaque decls all use same 4 bits per decl | 3080 | /// struct, union, enum, and opaque decls all use same 4 bits per decl |
| 3081 | const bits_per_decl = 4; | 3081 | const bits_per_decl = 4; |
| 3082 | const decls_per_u32 = 32 / bits_per_decl; | 3082 | const decls_per_u32 = 32 / bits_per_decl; |
| 3083 | /// struct, union, enum, and opaque decls all have maximum size of 10 u32 slots | 3083 | /// struct, union, enum, and opaque decls all have maximum size of 11 u32 slots |
| 3084 | /// (4 for src_hash + line + name + value + align + link_section + address_space) | 3084 | /// (4 for src_hash + line + name + value + doc_comment + align + link_section + address_space ) |
| 3085 | const max_decl_size = 10; | 3085 | const max_decl_size = 11; |
| 3086 | | 3086 | |
| 3087 | pub fn init(gpa: Allocator, payload: *ArrayListUnmanaged(u32), decl_count: u32, field_count: u32, comptime bits_per_field: u32, comptime max_field_size: u32) Allocator.Error!Self { | 3087 | pub fn init(gpa: Allocator, payload: *ArrayListUnmanaged(u32), decl_count: u32, field_count: u32, comptime bits_per_field: u32, comptime max_field_size: u32) Allocator.Error!Self { |
| 3088 | const payload_top = @intCast(u32, payload.items.len); | 3088 | const payload_top = @intCast(u32, payload.items.len); |
| ... | @@ -3193,6 +3193,7 @@ fn fnDecl( | ... | @@ -3193,6 +3193,7 @@ fn fnDecl( |
| 3193 | // missing function name already happened in scanDecls() | 3193 | // missing function name already happened in scanDecls() |
| 3194 | const fn_name_token = fn_proto.name_token orelse return error.AnalysisFail; | 3194 | const fn_name_token = fn_proto.name_token orelse return error.AnalysisFail; |
| 3195 | const fn_name_str_index = try astgen.identAsString(fn_name_token); | 3195 | const fn_name_str_index = try astgen.identAsString(fn_name_token); |
| | 3196 | const doc_comment_index = try docCommentAsString(astgen, fn_name_token - 1); |
| 3196 | | 3197 | |
| 3197 | // We insert this at the beginning so that its instruction index marks the | 3198 | // We insert this at the beginning so that its instruction index marks the |
| 3198 | // start of the top level declaration. | 3199 | // start of the top level declaration. |
| ... | @@ -3445,6 +3446,7 @@ fn fnDecl( | ... | @@ -3445,6 +3446,7 @@ fn fnDecl( |
| 3445 | } | 3446 | } |
| 3446 | wip_members.appendToDecl(fn_name_str_index); | 3447 | wip_members.appendToDecl(fn_name_str_index); |
| 3447 | wip_members.appendToDecl(block_inst); | 3448 | wip_members.appendToDecl(block_inst); |
| | 3449 | wip_members.appendToDecl(doc_comment_index); |
| 3448 | if (align_inst != .none) { | 3450 | if (align_inst != .none) { |
| 3449 | wip_members.appendToDecl(@enumToInt(align_inst)); | 3451 | wip_members.appendToDecl(@enumToInt(align_inst)); |
| 3450 | } | 3452 | } |
| ... | @@ -3472,6 +3474,7 @@ fn globalVarDecl( | ... | @@ -3472,6 +3474,7 @@ fn globalVarDecl( |
| 3472 | | 3474 | |
| 3473 | const name_token = var_decl.ast.mut_token + 1; | 3475 | const name_token = var_decl.ast.mut_token + 1; |
| 3474 | const name_str_index = try astgen.identAsString(name_token); | 3476 | const name_str_index = try astgen.identAsString(name_token); |
| | 3477 | const doc_comment_index = try docCommentAsString(astgen, var_decl.ast.mut_token); |
| 3475 | | 3478 | |
| 3476 | var block_scope: GenZir = .{ | 3479 | var block_scope: GenZir = .{ |
| 3477 | .parent = scope, | 3480 | .parent = scope, |
| ... | @@ -3594,6 +3597,7 @@ fn globalVarDecl( | ... | @@ -3594,6 +3597,7 @@ fn globalVarDecl( |
| 3594 | } | 3597 | } |
| 3595 | wip_members.appendToDecl(name_str_index); | 3598 | wip_members.appendToDecl(name_str_index); |
| 3596 | wip_members.appendToDecl(block_inst); | 3599 | wip_members.appendToDecl(block_inst); |
| | 3600 | wip_members.appendToDecl(doc_comment_index); // doc_comment wip |
| 3597 | if (align_inst != .none) { | 3601 | if (align_inst != .none) { |
| 3598 | wip_members.appendToDecl(@enumToInt(align_inst)); | 3602 | wip_members.appendToDecl(@enumToInt(align_inst)); |
| 3599 | } | 3603 | } |
| ... | @@ -3648,6 +3652,7 @@ fn comptimeDecl( | ... | @@ -3648,6 +3652,7 @@ fn comptimeDecl( |
| 3648 | } | 3652 | } |
| 3649 | wip_members.appendToDecl(0); | 3653 | wip_members.appendToDecl(0); |
| 3650 | wip_members.appendToDecl(block_inst); | 3654 | wip_members.appendToDecl(block_inst); |
| | 3655 | wip_members.appendToDecl(0); // no doc comments on comptime decls |
| 3651 | } | 3656 | } |
| 3652 | | 3657 | |
| 3653 | fn usingnamespaceDecl( | 3658 | fn usingnamespaceDecl( |
| ... | @@ -3699,6 +3704,7 @@ fn usingnamespaceDecl( | ... | @@ -3699,6 +3704,7 @@ fn usingnamespaceDecl( |
| 3699 | } | 3704 | } |
| 3700 | wip_members.appendToDecl(0); | 3705 | wip_members.appendToDecl(0); |
| 3701 | wip_members.appendToDecl(block_inst); | 3706 | wip_members.appendToDecl(block_inst); |
| | 3707 | wip_members.appendToDecl(0); // no doc comments on usingnamespace decls |
| 3702 | } | 3708 | } |
| 3703 | | 3709 | |
| 3704 | fn testDecl( | 3710 | fn testDecl( |
| ... | @@ -3802,6 +3808,7 @@ fn testDecl( | ... | @@ -3802,6 +3808,7 @@ fn testDecl( |
| 3802 | } | 3808 | } |
| 3803 | wip_members.appendToDecl(test_name); | 3809 | wip_members.appendToDecl(test_name); |
| 3804 | wip_members.appendToDecl(block_inst); | 3810 | wip_members.appendToDecl(block_inst); |
| | 3811 | wip_members.appendToDecl(0); // no doc comments on test decls |
| 3805 | } | 3812 | } |
| 3806 | | 3813 | |
| 3807 | fn structDeclInner( | 3814 | fn structDeclInner( |
| ... | @@ -8784,6 +8791,58 @@ fn identAsString(astgen: *AstGen, ident_token: Ast.TokenIndex) !u32 { | ... | @@ -8784,6 +8791,58 @@ fn identAsString(astgen: *AstGen, ident_token: Ast.TokenIndex) !u32 { |
| 8784 | } | 8791 | } |
| 8785 | } | 8792 | } |
| 8786 | | 8793 | |
| | 8794 | /// Adds a doc comment block to `string_bytes` by walking backwards from `end_token`. |
| | 8795 | /// `end_token` must point at the first token after the last doc coment line. |
| | 8796 | /// Returns 0 if no doc comment is present. |
| | 8797 | fn docCommentAsString(astgen: *AstGen, end_token: Ast.TokenIndex) !u32 { |
| | 8798 | const gpa = astgen.gpa; |
| | 8799 | const string_bytes = &astgen.string_bytes; |
| | 8800 | const str_index = @intCast(u32, string_bytes.items.len); |
| | 8801 | const token_tags = astgen.tree.tokens.items(.tag); |
| | 8802 | const token_starts = astgen.tree.tokens.items(.start); |
| | 8803 | |
| | 8804 | if (end_token == 0) return 0; |
| | 8805 | const start_token: u32 = blk: { |
| | 8806 | var tok = end_token - 1; |
| | 8807 | while (token_tags[tok] == .doc_comment) { |
| | 8808 | if (tok == 0) break; |
| | 8809 | tok -= 1; |
| | 8810 | } else { |
| | 8811 | tok += 1; |
| | 8812 | } |
| | 8813 | break :blk tok; |
| | 8814 | }; |
| | 8815 | if (start_token == end_token) return 0; |
| | 8816 | |
| | 8817 | const total_bytes = token_starts[end_token] - token_starts[start_token]; |
| | 8818 | try string_bytes.ensureUnusedCapacity(gpa, total_bytes); |
| | 8819 | |
| | 8820 | var current_token = start_token; |
| | 8821 | while (current_token < end_token) : (current_token += 1) { |
| | 8822 | const tok_bytes = astgen.tree.tokenSlice(current_token)[3..]; |
| | 8823 | string_bytes.appendSliceAssumeCapacity(tok_bytes); |
| | 8824 | if (current_token != end_token - 1) { |
| | 8825 | string_bytes.appendAssumeCapacity('\n'); |
| | 8826 | } |
| | 8827 | } |
| | 8828 | |
| | 8829 | const key = string_bytes.items[str_index..]; |
| | 8830 | const gop = try astgen.string_table.getOrPutContextAdapted(gpa, @as([]const u8, key), StringIndexAdapter{ |
| | 8831 | .bytes = string_bytes, |
| | 8832 | }, StringIndexContext{ |
| | 8833 | .bytes = string_bytes, |
| | 8834 | }); |
| | 8835 | |
| | 8836 | if (gop.found_existing) { |
| | 8837 | string_bytes.shrinkRetainingCapacity(str_index); |
| | 8838 | return gop.key_ptr.*; |
| | 8839 | } else { |
| | 8840 | gop.key_ptr.* = str_index; |
| | 8841 | try string_bytes.append(gpa, 0); |
| | 8842 | return str_index; |
| | 8843 | } |
| | 8844 | } |
| | 8845 | |
| 8787 | const IndexSlice = struct { index: u32, len: u32 }; | 8846 | const IndexSlice = struct { index: u32, len: u32 }; |
| 8788 | | 8847 | |
| 8789 | fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice { | 8848 | fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice { |