| author | |
| committer | |
| log | 12c2de6ee205857e9ca0bcef4aa4d901fc5cc772 |
| tree | 491f15df20182f428a92533e8efc2530c73c9dc2 |
| parent | f1b91bb41b2d810ecabf4c69cad91b24b3846b77 |
| parent | 8a697262099d64b2ff222dc9271493fe3b5f2b76 |
| signature |
Doc comments zir9 files changed, 212 insertions(+), 23 deletions(-)
lib/std/special/compiler_rt.zig+3-1| ... | ... | @@ -26,7 +26,9 @@ comptime { |
| 26 | 26 | if (builtin.zig_backend == .stage1) { |
| 27 | 27 | _ = @import("compiler_rt/atomics.zig"); |
| 28 | 28 | } |
| 29 | _ = @import("compiler_rt/clear_cache.zig").clear_cache; | |
| 29 | if (builtin.zig_backend != .stage2_llvm) { // TODO | |
| 30 | _ = @import("compiler_rt/clear_cache.zig").clear_cache; | |
| 31 | } | |
| 30 | 32 | |
| 31 | 33 | const __extenddftf2 = @import("compiler_rt/extendXfYf2.zig").__extenddftf2; |
| 32 | 34 | @export(__extenddftf2, .{ .name = "__extenddftf2", .linkage = linkage }); |
lib/std/zig/Ast.zig+18| ... | ... | @@ -2120,6 +2120,14 @@ pub const full = struct { |
| 2120 | 2120 | section_node: Node.Index, |
| 2121 | 2121 | init_node: Node.Index, |
| 2122 | 2122 | }; |
| 2123 | ||
| 2124 | pub fn firstToken(var_decl: VarDecl) TokenIndex { | |
| 2125 | return var_decl.visib_token orelse | |
| 2126 | var_decl.extern_export_token orelse | |
| 2127 | var_decl.threadlocal_token orelse | |
| 2128 | var_decl.comptime_token orelse | |
| 2129 | var_decl.ast.mut_token; | |
| 2130 | } | |
| 2123 | 2131 | }; |
| 2124 | 2132 | |
| 2125 | 2133 | pub const If = struct { |
| ... | ... | @@ -2168,6 +2176,10 @@ pub const full = struct { |
| 2168 | 2176 | value_expr: Node.Index, |
| 2169 | 2177 | align_expr: Node.Index, |
| 2170 | 2178 | }; |
| 2179 | ||
| 2180 | pub fn firstToken(cf: ContainerField) TokenIndex { | |
| 2181 | return cf.comptime_token orelse cf.ast.name_token; | |
| 2182 | } | |
| 2171 | 2183 | }; |
| 2172 | 2184 | |
| 2173 | 2185 | pub const FnProto = struct { |
| ... | ... | @@ -2197,6 +2209,12 @@ pub const full = struct { |
| 2197 | 2209 | type_expr: Node.Index, |
| 2198 | 2210 | }; |
| 2199 | 2211 | |
| 2212 | pub fn firstToken(fn_proto: FnProto) TokenIndex { | |
| 2213 | return fn_proto.visib_token orelse | |
| 2214 | fn_proto.extern_export_inline_token orelse | |
| 2215 | fn_proto.ast.fn_token; | |
| 2216 | } | |
| 2217 | ||
| 2200 | 2218 | /// Abstracts over the fact that anytype and ... are not included |
| 2201 | 2219 | /// in the params slice, since they are simple identifiers and |
| 2202 | 2220 | /// not sub-expressions. |
src/AstGen.zig+104-9| ... | ... | @@ -1171,7 +1171,7 @@ fn fnProtoExpr( |
| 1171 | 1171 | const main_tokens = tree.nodes.items(.main_token); |
| 1172 | 1172 | const name_token = param.name_token orelse main_tokens[param_type_node]; |
| 1173 | 1173 | const tag: Zir.Inst.Tag = if (is_comptime) .param_comptime else .param; |
| 1174 | const param_inst = try block_scope.addParam(&param_gz, tag, name_token, param_name); | |
| 1174 | const param_inst = try block_scope.addParam(&param_gz, tag, name_token, param_name, param.first_doc_comment); | |
| 1175 | 1175 | assert(param_inst_expected == param_inst); |
| 1176 | 1176 | } |
| 1177 | 1177 | } |
| ... | ... | @@ -3080,9 +3080,9 @@ const WipMembers = struct { |
| 3080 | 3080 | /// struct, union, enum, and opaque decls all use same 4 bits per decl |
| 3081 | 3081 | const bits_per_decl = 4; |
| 3082 | 3082 | const decls_per_u32 = 32 / bits_per_decl; |
| 3083 | /// struct, union, enum, and opaque decls all have maximum size of 10 u32 slots | |
| 3084 | /// (4 for src_hash + line + name + value + align + link_section + address_space) | |
| 3085 | const max_decl_size = 10; | |
| 3083 | /// struct, union, enum, and opaque decls all have maximum size of 11 u32 slots | |
| 3084 | /// (4 for src_hash + line + name + value + doc_comment + align + link_section + address_space ) | |
| 3085 | const max_decl_size = 11; | |
| 3086 | 3086 | |
| 3087 | 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 | 3088 | const payload_top = @intCast(u32, payload.items.len); |
| ... | ... | @@ -3236,6 +3236,9 @@ fn fnDecl( |
| 3236 | 3236 | const maybe_inline_token = fn_proto.extern_export_inline_token orelse break :blk false; |
| 3237 | 3237 | break :blk token_tags[maybe_inline_token] == .keyword_inline; |
| 3238 | 3238 | }; |
| 3239 | ||
| 3240 | const doc_comment_index = try astgen.docCommentAsString(fn_proto.firstToken()); | |
| 3241 | ||
| 3239 | 3242 | const has_section_or_addrspace = fn_proto.ast.section_expr != 0 or fn_proto.ast.addrspace_expr != 0; |
| 3240 | 3243 | wip_members.nextDecl(is_pub, is_export, fn_proto.ast.align_expr != 0, has_section_or_addrspace); |
| 3241 | 3244 | |
| ... | ... | @@ -3294,7 +3297,7 @@ fn fnDecl( |
| 3294 | 3297 | const main_tokens = tree.nodes.items(.main_token); |
| 3295 | 3298 | const name_token = param.name_token orelse main_tokens[param_type_node]; |
| 3296 | 3299 | const tag: Zir.Inst.Tag = if (is_comptime) .param_comptime else .param; |
| 3297 | const param_inst = try decl_gz.addParam(&param_gz, tag, name_token, param_name); | |
| 3300 | const param_inst = try decl_gz.addParam(&param_gz, tag, name_token, param_name, param.first_doc_comment); | |
| 3298 | 3301 | assert(param_inst_expected == param_inst); |
| 3299 | 3302 | break :param indexToRef(param_inst); |
| 3300 | 3303 | }; |
| ... | ... | @@ -3445,6 +3448,7 @@ fn fnDecl( |
| 3445 | 3448 | } |
| 3446 | 3449 | wip_members.appendToDecl(fn_name_str_index); |
| 3447 | 3450 | wip_members.appendToDecl(block_inst); |
| 3451 | wip_members.appendToDecl(doc_comment_index); | |
| 3448 | 3452 | if (align_inst != .none) { |
| 3449 | 3453 | wip_members.appendToDecl(@enumToInt(align_inst)); |
| 3450 | 3454 | } |
| ... | ... | @@ -3519,6 +3523,8 @@ fn globalVarDecl( |
| 3519 | 3523 | break :blk lib_name_str.index; |
| 3520 | 3524 | } else 0; |
| 3521 | 3525 | |
| 3526 | const doc_comment_index = try astgen.docCommentAsString(var_decl.firstToken()); | |
| 3527 | ||
| 3522 | 3528 | assert(var_decl.comptime_token == null); // handled by parser |
| 3523 | 3529 | |
| 3524 | 3530 | const var_inst: Zir.Inst.Ref = if (var_decl.ast.init_node != 0) vi: { |
| ... | ... | @@ -3594,6 +3600,7 @@ fn globalVarDecl( |
| 3594 | 3600 | } |
| 3595 | 3601 | wip_members.appendToDecl(name_str_index); |
| 3596 | 3602 | wip_members.appendToDecl(block_inst); |
| 3603 | wip_members.appendToDecl(doc_comment_index); // doc_comment wip | |
| 3597 | 3604 | if (align_inst != .none) { |
| 3598 | 3605 | wip_members.appendToDecl(@enumToInt(align_inst)); |
| 3599 | 3606 | } |
| ... | ... | @@ -3648,6 +3655,7 @@ fn comptimeDecl( |
| 3648 | 3655 | } |
| 3649 | 3656 | wip_members.appendToDecl(0); |
| 3650 | 3657 | wip_members.appendToDecl(block_inst); |
| 3658 | wip_members.appendToDecl(0); // no doc comments on comptime decls | |
| 3651 | 3659 | } |
| 3652 | 3660 | |
| 3653 | 3661 | fn usingnamespaceDecl( |
| ... | ... | @@ -3699,6 +3707,7 @@ fn usingnamespaceDecl( |
| 3699 | 3707 | } |
| 3700 | 3708 | wip_members.appendToDecl(0); |
| 3701 | 3709 | wip_members.appendToDecl(block_inst); |
| 3710 | wip_members.appendToDecl(0); // no doc comments on usingnamespace decls | |
| 3702 | 3711 | } |
| 3703 | 3712 | |
| 3704 | 3713 | fn testDecl( |
| ... | ... | @@ -3802,6 +3811,7 @@ fn testDecl( |
| 3802 | 3811 | } |
| 3803 | 3812 | wip_members.appendToDecl(test_name); |
| 3804 | 3813 | wip_members.appendToDecl(block_inst); |
| 3814 | wip_members.appendToDecl(0); // no doc comments on test decls | |
| 3805 | 3815 | } |
| 3806 | 3816 | |
| 3807 | 3817 | fn structDeclInner( |
| ... | ... | @@ -3857,7 +3867,7 @@ fn structDeclInner( |
| 3857 | 3867 | const field_count = @intCast(u32, container_decl.ast.members.len - decl_count); |
| 3858 | 3868 | |
| 3859 | 3869 | const bits_per_field = 4; |
| 3860 | const max_field_size = 4; | |
| 3870 | const max_field_size = 5; | |
| 3861 | 3871 | var wip_members = try WipMembers.init(gpa, &astgen.scratch, decl_count, field_count, bits_per_field, max_field_size); |
| 3862 | 3872 | defer wip_members.deinit(); |
| 3863 | 3873 | |
| ... | ... | @@ -3881,6 +3891,9 @@ fn structDeclInner( |
| 3881 | 3891 | try typeExpr(&block_scope, &namespace.base, member.ast.type_expr); |
| 3882 | 3892 | wip_members.appendToField(@enumToInt(field_type)); |
| 3883 | 3893 | |
| 3894 | const doc_comment_index = try astgen.docCommentAsString(member.firstToken()); | |
| 3895 | wip_members.appendToField(doc_comment_index); | |
| 3896 | ||
| 3884 | 3897 | known_has_bits = known_has_bits or nodeImpliesRuntimeBits(tree, member.ast.type_expr); |
| 3885 | 3898 | |
| 3886 | 3899 | const have_align = member.ast.align_expr != 0; |
| ... | ... | @@ -3979,7 +3992,7 @@ fn unionDeclInner( |
| 3979 | 3992 | .none; |
| 3980 | 3993 | |
| 3981 | 3994 | const bits_per_field = 4; |
| 3982 | const max_field_size = 4; | |
| 3995 | const max_field_size = 5; | |
| 3983 | 3996 | var wip_members = try WipMembers.init(gpa, &astgen.scratch, decl_count, field_count, bits_per_field, max_field_size); |
| 3984 | 3997 | defer wip_members.deinit(); |
| 3985 | 3998 | |
| ... | ... | @@ -3995,6 +4008,9 @@ fn unionDeclInner( |
| 3995 | 4008 | const field_name = try astgen.identAsString(member.ast.name_token); |
| 3996 | 4009 | wip_members.appendToField(field_name); |
| 3997 | 4010 | |
| 4011 | const doc_comment_index = try astgen.docCommentAsString(member.firstToken()); | |
| 4012 | wip_members.appendToField(doc_comment_index); | |
| 4013 | ||
| 3998 | 4014 | const have_type = member.ast.type_expr != 0; |
| 3999 | 4015 | const have_align = member.ast.align_expr != 0; |
| 4000 | 4016 | const have_value = member.ast.value_expr != 0; |
| ... | ... | @@ -4258,7 +4274,7 @@ fn containerDecl( |
| 4258 | 4274 | .none; |
| 4259 | 4275 | |
| 4260 | 4276 | const bits_per_field = 1; |
| 4261 | const max_field_size = 2; | |
| 4277 | const max_field_size = 3; | |
| 4262 | 4278 | var wip_members = try WipMembers.init(gpa, &astgen.scratch, @intCast(u32, counts.decls), @intCast(u32, counts.total_fields), bits_per_field, max_field_size); |
| 4263 | 4279 | defer wip_members.deinit(); |
| 4264 | 4280 | |
| ... | ... | @@ -4276,6 +4292,9 @@ fn containerDecl( |
| 4276 | 4292 | const field_name = try astgen.identAsString(member.ast.name_token); |
| 4277 | 4293 | wip_members.appendToField(field_name); |
| 4278 | 4294 | |
| 4295 | const doc_comment_index = try astgen.docCommentAsString(member.firstToken()); | |
| 4296 | wip_members.appendToField(doc_comment_index); | |
| 4297 | ||
| 4279 | 4298 | const have_value = member.ast.value_expr != 0; |
| 4280 | 4299 | wip_members.nextField(bits_per_field, .{have_value}); |
| 4281 | 4300 | |
| ... | ... | @@ -4506,8 +4525,11 @@ fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir |
| 4506 | 4525 | switch (token_tags[tok_i]) { |
| 4507 | 4526 | .doc_comment, .comma => {}, |
| 4508 | 4527 | .identifier => { |
| 4528 | try astgen.extra.ensureUnusedCapacity(gpa, 2); | |
| 4509 | 4529 | const str_index = try astgen.identAsString(tok_i); |
| 4510 | try astgen.extra.append(gpa, str_index); | |
| 4530 | astgen.extra.appendAssumeCapacity(str_index); | |
| 4531 | const doc_comment_index = try astgen.docCommentAsString(tok_i); | |
| 4532 | astgen.extra.appendAssumeCapacity(doc_comment_index); | |
| 4511 | 4533 | fields_len += 1; |
| 4512 | 4534 | }, |
| 4513 | 4535 | .r_brace => break, |
| ... | ... | @@ -8784,6 +8806,72 @@ fn identAsString(astgen: *AstGen, ident_token: Ast.TokenIndex) !u32 { |
| 8784 | 8806 | } |
| 8785 | 8807 | } |
| 8786 | 8808 | |
| 8809 | /// Adds a doc comment block to `string_bytes` by walking backwards from `end_token`. | |
| 8810 | /// `end_token` must point at the first token after the last doc coment line. | |
| 8811 | /// Returns 0 if no doc comment is present. | |
| 8812 | fn docCommentAsString(astgen: *AstGen, end_token: Ast.TokenIndex) !u32 { | |
| 8813 | if (end_token == 0) return @as(u32, 0); | |
| 8814 | ||
| 8815 | const token_tags = astgen.tree.tokens.items(.tag); | |
| 8816 | ||
| 8817 | var tok = end_token - 1; | |
| 8818 | while (token_tags[tok] == .doc_comment) { | |
| 8819 | if (tok == 0) break; | |
| 8820 | tok -= 1; | |
| 8821 | } else { | |
| 8822 | tok += 1; | |
| 8823 | } | |
| 8824 | return docCommentAsStringFromFirst(astgen, end_token, tok); | |
| 8825 | } | |
| 8826 | ||
| 8827 | /// end_token must be > the index of the last doc comment. | |
| 8828 | fn docCommentAsStringFromFirst( | |
| 8829 | astgen: *AstGen, | |
| 8830 | end_token: Ast.TokenIndex, | |
| 8831 | start_token: Ast.TokenIndex, | |
| 8832 | ) !u32 { | |
| 8833 | if (start_token == end_token) return 0; | |
| 8834 | ||
| 8835 | const gpa = astgen.gpa; | |
| 8836 | const string_bytes = &astgen.string_bytes; | |
| 8837 | const str_index = @intCast(u32, string_bytes.items.len); | |
| 8838 | const token_starts = astgen.tree.tokens.items(.start); | |
| 8839 | const token_tags = astgen.tree.tokens.items(.tag); | |
| 8840 | ||
| 8841 | const total_bytes = token_starts[end_token] - token_starts[start_token]; | |
| 8842 | try string_bytes.ensureUnusedCapacity(gpa, total_bytes); | |
| 8843 | ||
| 8844 | var current_token = start_token; | |
| 8845 | while (current_token < end_token) : (current_token += 1) { | |
| 8846 | switch (token_tags[current_token]) { | |
| 8847 | .doc_comment => { | |
| 8848 | const tok_bytes = astgen.tree.tokenSlice(current_token)[3..]; | |
| 8849 | string_bytes.appendSliceAssumeCapacity(tok_bytes); | |
| 8850 | if (current_token != end_token - 1) { | |
| 8851 | string_bytes.appendAssumeCapacity('\n'); | |
| 8852 | } | |
| 8853 | }, | |
| 8854 | else => break, | |
| 8855 | } | |
| 8856 | } | |
| 8857 | ||
| 8858 | const key = string_bytes.items[str_index..]; | |
| 8859 | const gop = try astgen.string_table.getOrPutContextAdapted(gpa, @as([]const u8, key), StringIndexAdapter{ | |
| 8860 | .bytes = string_bytes, | |
| 8861 | }, StringIndexContext{ | |
| 8862 | .bytes = string_bytes, | |
| 8863 | }); | |
| 8864 | ||
| 8865 | if (gop.found_existing) { | |
| 8866 | string_bytes.shrinkRetainingCapacity(str_index); | |
| 8867 | return gop.key_ptr.*; | |
| 8868 | } else { | |
| 8869 | gop.key_ptr.* = str_index; | |
| 8870 | try string_bytes.append(gpa, 0); | |
| 8871 | return str_index; | |
| 8872 | } | |
| 8873 | } | |
| 8874 | ||
| 8787 | 8875 | const IndexSlice = struct { index: u32, len: u32 }; |
| 8788 | 8876 | |
| 8789 | 8877 | fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice { |
| ... | ... | @@ -9629,6 +9717,7 @@ const GenZir = struct { |
| 9629 | 9717 | /// Absolute token index. This function does the conversion to Decl offset. |
| 9630 | 9718 | abs_tok_index: Ast.TokenIndex, |
| 9631 | 9719 | name: u32, |
| 9720 | first_doc_comment: ?Ast.TokenIndex, | |
| 9632 | 9721 | ) !Zir.Inst.Index { |
| 9633 | 9722 | const gpa = gz.astgen.gpa; |
| 9634 | 9723 | const param_body = param_gz.instructionsSlice(); |
| ... | ... | @@ -9636,8 +9725,14 @@ const GenZir = struct { |
| 9636 | 9725 | try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.Param).Struct.fields.len + |
| 9637 | 9726 | param_body.len); |
| 9638 | 9727 | |
| 9728 | const doc_comment_index = if (first_doc_comment) |first| | |
| 9729 | try gz.astgen.docCommentAsStringFromFirst(abs_tok_index, first) | |
| 9730 | else | |
| 9731 | 0; | |
| 9732 | ||
| 9639 | 9733 | const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Param{ |
| 9640 | 9734 | .name = name, |
| 9735 | .doc_comment = doc_comment_index, | |
| 9641 | 9736 | .body_len = @intCast(u32, param_body.len), |
| 9642 | 9737 | }); |
| 9643 | 9738 | gz.astgen.extra.appendSliceAssumeCapacity(param_body); |
src/Module.zig+4-4| ... | ... | @@ -558,14 +558,14 @@ pub const Decl = struct { |
| 558 | 558 | if (!decl.has_align) return .none; |
| 559 | 559 | assert(decl.zir_decl_index != 0); |
| 560 | 560 | const zir = decl.getFileScope().zir; |
| 561 | return @intToEnum(Zir.Inst.Ref, zir.extra[decl.zir_decl_index + 7]); | |
| 561 | return @intToEnum(Zir.Inst.Ref, zir.extra[decl.zir_decl_index + 8]); | |
| 562 | 562 | } |
| 563 | 563 | |
| 564 | 564 | pub fn zirLinksectionRef(decl: Decl) Zir.Inst.Ref { |
| 565 | 565 | if (!decl.has_linksection_or_addrspace) return .none; |
| 566 | 566 | assert(decl.zir_decl_index != 0); |
| 567 | 567 | const zir = decl.getFileScope().zir; |
| 568 | const extra_index = decl.zir_decl_index + 7 + @boolToInt(decl.has_align); | |
| 568 | const extra_index = decl.zir_decl_index + 8 + @boolToInt(decl.has_align); | |
| 569 | 569 | return @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]); |
| 570 | 570 | } |
| 571 | 571 | |
| ... | ... | @@ -573,7 +573,7 @@ pub const Decl = struct { |
| 573 | 573 | if (!decl.has_linksection_or_addrspace) return .none; |
| 574 | 574 | assert(decl.zir_decl_index != 0); |
| 575 | 575 | const zir = decl.getFileScope().zir; |
| 576 | const extra_index = decl.zir_decl_index + 7 + @boolToInt(decl.has_align) + 1; | |
| 576 | const extra_index = decl.zir_decl_index + 8 + @boolToInt(decl.has_align) + 1; | |
| 577 | 577 | return @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]); |
| 578 | 578 | } |
| 579 | 579 | |
| ... | ... | @@ -4011,7 +4011,7 @@ pub fn scanNamespace( |
| 4011 | 4011 | cur_bit_bag >>= 4; |
| 4012 | 4012 | |
| 4013 | 4013 | const decl_sub_index = extra_index; |
| 4014 | extra_index += 7; // src_hash(4) + line(1) + name(1) + value(1) | |
| 4014 | extra_index += 8; // src_hash(4) + line(1) + name(1) + value(1) + doc_comment(1) | |
| 4015 | 4015 | extra_index += @truncate(u1, flags >> 2); // Align |
| 4016 | 4016 | extra_index += @as(u2, @truncate(u1, flags >> 3)) * 2; // Link section or address space, consists of 2 Refs |
| 4017 | 4017 |
src/Sema.zig+15-3| ... | ... | @@ -1916,6 +1916,9 @@ fn zirEnumDecl( |
| 1916 | 1916 | const field_name_zir = sema.code.nullTerminatedString(sema.code.extra[extra_index]); |
| 1917 | 1917 | extra_index += 1; |
| 1918 | 1918 | |
| 1919 | // doc comment | |
| 1920 | extra_index += 1; | |
| 1921 | ||
| 1919 | 1922 | // This string needs to outlive the ZIR code. |
| 1920 | 1923 | const field_name = try new_decl_arena_allocator.dupe(u8, field_name_zir); |
| 1921 | 1924 | |
| ... | ... | @@ -2103,7 +2106,6 @@ fn zirErrorSetDecl( |
| 2103 | 2106 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 2104 | 2107 | const src = inst_data.src(); |
| 2105 | 2108 | const extra = sema.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index); |
| 2106 | const fields = sema.code.extra[extra.end..][0..extra.data.fields_len]; | |
| 2107 | 2109 | |
| 2108 | 2110 | var new_decl_arena = std.heap.ArenaAllocator.init(gpa); |
| 2109 | 2111 | errdefer new_decl_arena.deinit(); |
| ... | ... | @@ -2121,8 +2123,12 @@ fn zirErrorSetDecl( |
| 2121 | 2123 | errdefer sema.mod.abortAnonDecl(new_decl); |
| 2122 | 2124 | |
| 2123 | 2125 | var names = Module.ErrorSet.NameMap{}; |
| 2124 | try names.ensureUnusedCapacity(new_decl_arena_allocator, fields.len); | |
| 2125 | for (fields) |str_index| { | |
| 2126 | try names.ensureUnusedCapacity(new_decl_arena_allocator, extra.data.fields_len); | |
| 2127 | ||
| 2128 | var extra_index = @intCast(u32, extra.end); | |
| 2129 | const extra_index_end = extra_index + (extra.data.fields_len * 2); | |
| 2130 | while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string | |
| 2131 | const str_index = sema.code.extra[extra_index]; | |
| 2126 | 2132 | const name = try new_decl_arena_allocator.dupe(u8, sema.code.nullTerminatedString(str_index)); |
| 2127 | 2133 | |
| 2128 | 2134 | // TODO: This check should be performed in AstGen instead. |
| ... | ... | @@ -16313,6 +16319,9 @@ fn semaStructFields( |
| 16313 | 16319 | const field_type_ref = @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]); |
| 16314 | 16320 | extra_index += 1; |
| 16315 | 16321 | |
| 16322 | // doc_comment | |
| 16323 | extra_index += 1; | |
| 16324 | ||
| 16316 | 16325 | // This string needs to outlive the ZIR code. |
| 16317 | 16326 | const field_name = try decl_arena_allocator.dupe(u8, field_name_zir); |
| 16318 | 16327 | const field_ty: Type = if (field_type_ref == .none) |
| ... | ... | @@ -16502,6 +16511,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 16502 | 16511 | const field_name_zir = zir.nullTerminatedString(zir.extra[extra_index]); |
| 16503 | 16512 | extra_index += 1; |
| 16504 | 16513 | |
| 16514 | // doc_comment | |
| 16515 | extra_index += 1; | |
| 16516 | ||
| 16505 | 16517 | const field_type_ref: Zir.Inst.Ref = if (has_type) blk: { |
| 16506 | 16518 | const field_type_ref = @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]); |
| 16507 | 16519 | extra_index += 1; |
src/Zir.zig+15-2| ... | ... | @@ -2571,6 +2571,7 @@ pub const Inst = struct { |
| 2571 | 2571 | /// - if there is a 0 byte at the position `name` indexes, it indicates |
| 2572 | 2572 | /// this is a test decl, and the name starts at `name+1`. |
| 2573 | 2573 | /// value: Index, |
| 2574 | /// doc_comment: u32, // 0 if no doc comment | |
| 2574 | 2575 | /// align: Ref, // if corresponding bit is set |
| 2575 | 2576 | /// link_section_or_address_space: { // if corresponding bit is set. |
| 2576 | 2577 | /// link_section: Ref, |
| ... | ... | @@ -2588,6 +2589,7 @@ pub const Inst = struct { |
| 2588 | 2589 | /// field_name: u32, |
| 2589 | 2590 | /// field_type: Ref, |
| 2590 | 2591 | /// - if none, means `anytype`. |
| 2592 | /// doc_comment: u32, // 0 if no doc comment | |
| 2591 | 2593 | /// align: Ref, // if corresponding bit is set |
| 2592 | 2594 | /// default_value: Ref, // if corresponding bit is set |
| 2593 | 2595 | /// } |
| ... | ... | @@ -2638,6 +2640,7 @@ pub const Inst = struct { |
| 2638 | 2640 | /// - if there is a 0 byte at the position `name` indexes, it indicates |
| 2639 | 2641 | /// this is a test decl, and the name starts at `name+1`. |
| 2640 | 2642 | /// value: Index, |
| 2643 | /// doc_comment: u32, // 0 if no doc_comment | |
| 2641 | 2644 | /// align: Ref, // if corresponding bit is set |
| 2642 | 2645 | /// link_section_or_address_space: { // if corresponding bit is set. |
| 2643 | 2646 | /// link_section: Ref, |
| ... | ... | @@ -2649,6 +2652,7 @@ pub const Inst = struct { |
| 2649 | 2652 | /// - the bit is whether corresponding field has an value expression |
| 2650 | 2653 | /// 9. fields: { // for every fields_len |
| 2651 | 2654 | /// field_name: u32, |
| 2655 | /// doc_comment: u32, // 0 if no doc_comment | |
| 2652 | 2656 | /// value: Ref, // if corresponding bit is set |
| 2653 | 2657 | /// } |
| 2654 | 2658 | pub const EnumDecl = struct { |
| ... | ... | @@ -2686,6 +2690,7 @@ pub const Inst = struct { |
| 2686 | 2690 | /// - if there is a 0 byte at the position `name` indexes, it indicates |
| 2687 | 2691 | /// this is a test decl, and the name starts at `name+1`. |
| 2688 | 2692 | /// value: Index, |
| 2693 | /// doc_comment: u32, // 0 if no doc comment | |
| 2689 | 2694 | /// align: Ref, // if corresponding bit is set |
| 2690 | 2695 | /// link_section_or_address_space: { // if corresponding bit is set. |
| 2691 | 2696 | /// link_section: Ref, |
| ... | ... | @@ -2701,6 +2706,7 @@ pub const Inst = struct { |
| 2701 | 2706 | /// 0bX000: unused |
| 2702 | 2707 | /// 9. fields: { // for every fields_len |
| 2703 | 2708 | /// field_name: u32, // null terminated string index |
| 2709 | /// doc_comment: u32, // 0 if no doc comment | |
| 2704 | 2710 | /// field_type: Ref, // if corresponding bit is set |
| 2705 | 2711 | /// - if none, means `anytype`. |
| 2706 | 2712 | /// align: Ref, // if corresponding bit is set |
| ... | ... | @@ -2745,6 +2751,7 @@ pub const Inst = struct { |
| 2745 | 2751 | /// - if there is a 0 byte at the position `name` indexes, it indicates |
| 2746 | 2752 | /// this is a test decl, and the name starts at `name+1`. |
| 2747 | 2753 | /// value: Index, |
| 2754 | /// doc_comment: u32, // 0 if no doc comment, | |
| 2748 | 2755 | /// align: Ref, // if corresponding bit is set |
| 2749 | 2756 | /// link_section_or_address_space: { // if corresponding bit is set. |
| 2750 | 2757 | /// link_section: Ref, |
| ... | ... | @@ -2760,7 +2767,11 @@ pub const Inst = struct { |
| 2760 | 2767 | }; |
| 2761 | 2768 | }; |
| 2762 | 2769 | |
| 2763 | /// Trailing: field_name: u32 // for every field: null terminated string index | |
| 2770 | /// Trailing: | |
| 2771 | /// { // for every fields_len | |
| 2772 | /// field_name: u32 // null terminated string index | |
| 2773 | /// doc_comment: u32 // null terminated string index | |
| 2774 | /// } | |
| 2764 | 2775 | pub const ErrorSetDecl = struct { |
| 2765 | 2776 | fields_len: u32, |
| 2766 | 2777 | }; |
| ... | ... | @@ -2899,6 +2910,8 @@ pub const Inst = struct { |
| 2899 | 2910 | pub const Param = struct { |
| 2900 | 2911 | /// Null-terminated string index. |
| 2901 | 2912 | name: u32, |
| 2913 | /// 0 if no doc comment | |
| 2914 | doc_comment: u32, | |
| 2902 | 2915 | /// The body contains the type of the parameter. |
| 2903 | 2916 | body_len: u32, |
| 2904 | 2917 | }; |
| ... | ... | @@ -3001,7 +3014,7 @@ pub const DeclIterator = struct { |
| 3001 | 3014 | const sub_index = @intCast(u32, it.extra_index); |
| 3002 | 3015 | it.extra_index += 5; // src_hash(4) + line(1) |
| 3003 | 3016 | const name = it.zir.nullTerminatedString(it.zir.extra[it.extra_index]); |
| 3004 | it.extra_index += 2; // name(1) + value(1) | |
| 3017 | it.extra_index += 3; // name(1) + value(1) + doc_comment(1) | |
| 3005 | 3018 | it.extra_index += @truncate(u1, flags >> 2); |
| 3006 | 3019 | it.extra_index += @truncate(u1, flags >> 3); |
| 3007 | 3020 |
src/print_zir.zig+47-3| ... | ... | @@ -785,6 +785,12 @@ const Writer = struct { |
| 785 | 785 | try stream.print("\"{}\", ", .{ |
| 786 | 786 | std.zig.fmtEscapes(self.code.nullTerminatedString(extra.data.name)), |
| 787 | 787 | }); |
| 788 | ||
| 789 | if (extra.data.doc_comment != 0) { | |
| 790 | try stream.writeAll("\n"); | |
| 791 | try self.writeDocComment(stream, extra.data.doc_comment); | |
| 792 | try stream.writeByteNTimes(' ', self.indent); | |
| 793 | } | |
| 788 | 794 | try self.writeBracedBody(stream, body); |
| 789 | 795 | try stream.writeAll(") "); |
| 790 | 796 | try self.writeSrc(stream, inst_data.src()); |
| ... | ... | @@ -1207,6 +1213,10 @@ const Writer = struct { |
| 1207 | 1213 | extra_index += 1; |
| 1208 | 1214 | const field_type = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]); |
| 1209 | 1215 | extra_index += 1; |
| 1216 | const doc_comment_index = self.code.extra[extra_index]; | |
| 1217 | extra_index += 1; | |
| 1218 | ||
| 1219 | try self.writeDocComment(stream, doc_comment_index); | |
| 1210 | 1220 | |
| 1211 | 1221 | try stream.writeByteNTimes(' ', self.indent); |
| 1212 | 1222 | try self.writeFlag(stream, "comptime ", is_comptime); |
| ... | ... | @@ -1332,6 +1342,10 @@ const Writer = struct { |
| 1332 | 1342 | |
| 1333 | 1343 | const field_name = self.code.nullTerminatedString(self.code.extra[extra_index]); |
| 1334 | 1344 | extra_index += 1; |
| 1345 | const doc_comment_index = self.code.extra[extra_index]; | |
| 1346 | extra_index += 1; | |
| 1347 | ||
| 1348 | try self.writeDocComment(stream, doc_comment_index); | |
| 1335 | 1349 | try stream.writeByteNTimes(' ', self.indent); |
| 1336 | 1350 | try stream.print("{}", .{std.zig.fmtId(field_name)}); |
| 1337 | 1351 | |
| ... | ... | @@ -1398,6 +1412,9 @@ const Writer = struct { |
| 1398 | 1412 | extra_index += 1; |
| 1399 | 1413 | const decl_index = self.code.extra[extra_index]; |
| 1400 | 1414 | extra_index += 1; |
| 1415 | const doc_comment_index = self.code.extra[extra_index]; | |
| 1416 | extra_index += 1; | |
| 1417 | ||
| 1401 | 1418 | const align_inst: Zir.Inst.Ref = if (!has_align) .none else inst: { |
| 1402 | 1419 | const inst = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]); |
| 1403 | 1420 | extra_index += 1; |
| ... | ... | @@ -1416,12 +1433,13 @@ const Writer = struct { |
| 1416 | 1433 | |
| 1417 | 1434 | const pub_str = if (is_pub) "pub " else ""; |
| 1418 | 1435 | const hash_bytes = @bitCast([16]u8, hash_u32s.*); |
| 1419 | try stream.writeByteNTimes(' ', self.indent); | |
| 1420 | 1436 | if (decl_name_index == 0) { |
| 1437 | try stream.writeByteNTimes(' ', self.indent); | |
| 1421 | 1438 | const name = if (is_exported) "usingnamespace" else "comptime"; |
| 1422 | 1439 | try stream.writeAll(pub_str); |
| 1423 | 1440 | try stream.writeAll(name); |
| 1424 | 1441 | } else if (decl_name_index == 1) { |
| 1442 | try stream.writeByteNTimes(' ', self.indent); | |
| 1425 | 1443 | try stream.writeAll("test"); |
| 1426 | 1444 | } else { |
| 1427 | 1445 | const raw_decl_name = self.code.nullTerminatedString(decl_name_index); |
| ... | ... | @@ -1431,6 +1449,10 @@ const Writer = struct { |
| 1431 | 1449 | raw_decl_name; |
| 1432 | 1450 | const test_str = if (raw_decl_name.len == 0) "test " else ""; |
| 1433 | 1451 | const export_str = if (is_exported) "export " else ""; |
| 1452 | ||
| 1453 | try self.writeDocComment(stream, doc_comment_index); | |
| 1454 | ||
| 1455 | try stream.writeByteNTimes(' ', self.indent); | |
| 1434 | 1456 | try stream.print("[{d}] {s}{s}{s}{}", .{ |
| 1435 | 1457 | sub_index, pub_str, test_str, export_str, std.zig.fmtId(decl_name), |
| 1436 | 1458 | }); |
| ... | ... | @@ -1556,6 +1578,11 @@ const Writer = struct { |
| 1556 | 1578 | const field_name = self.code.nullTerminatedString(self.code.extra[extra_index]); |
| 1557 | 1579 | extra_index += 1; |
| 1558 | 1580 | |
| 1581 | const doc_comment_index = self.code.extra[extra_index]; | |
| 1582 | extra_index += 1; | |
| 1583 | ||
| 1584 | try self.writeDocComment(stream, doc_comment_index); | |
| 1585 | ||
| 1559 | 1586 | try stream.writeByteNTimes(' ', self.indent); |
| 1560 | 1587 | try stream.print("{}", .{std.zig.fmtId(field_name)}); |
| 1561 | 1588 | |
| ... | ... | @@ -1619,17 +1646,23 @@ const Writer = struct { |
| 1619 | 1646 | ) !void { |
| 1620 | 1647 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; |
| 1621 | 1648 | const extra = self.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index); |
| 1622 | const fields = self.code.extra[extra.end..][0..extra.data.fields_len]; | |
| 1623 | 1649 | |
| 1624 | 1650 | try stream.print("{s}, ", .{@tagName(name_strategy)}); |
| 1625 | 1651 | |
| 1626 | 1652 | try stream.writeAll("{\n"); |
| 1627 | 1653 | self.indent += 2; |
| 1628 | for (fields) |str_index| { | |
| 1654 | ||
| 1655 | var extra_index = @intCast(u32, extra.end); | |
| 1656 | const extra_index_end = extra_index + (extra.data.fields_len * 2); | |
| 1657 | while (extra_index < extra_index_end) : (extra_index += 2) { | |
| 1658 | const str_index = self.code.extra[extra_index]; | |
| 1629 | 1659 | const name = self.code.nullTerminatedString(str_index); |
| 1660 | const doc_comment_index = self.code.extra[extra_index + 1]; | |
| 1661 | try self.writeDocComment(stream, doc_comment_index); | |
| 1630 | 1662 | try stream.writeByteNTimes(' ', self.indent); |
| 1631 | 1663 | try stream.print("{},\n", .{std.zig.fmtId(name)}); |
| 1632 | 1664 | } |
| 1665 | ||
| 1633 | 1666 | self.indent -= 2; |
| 1634 | 1667 | try stream.writeByteNTimes(' ', self.indent); |
| 1635 | 1668 | try stream.writeAll("}) "); |
| ... | ... | @@ -2121,6 +2154,17 @@ const Writer = struct { |
| 2121 | 2154 | } |
| 2122 | 2155 | } |
| 2123 | 2156 | |
| 2157 | fn writeDocComment(self: *Writer, stream: anytype, doc_comment_index: u32) !void { | |
| 2158 | if (doc_comment_index != 0) { | |
| 2159 | const doc_comment = self.code.nullTerminatedString(doc_comment_index); | |
| 2160 | var it = std.mem.tokenize(u8, doc_comment, "\n"); | |
| 2161 | while (it.next()) |doc_line| { | |
| 2162 | try stream.writeByteNTimes(' ', self.indent); | |
| 2163 | try stream.print("///{s}\n", .{doc_line}); | |
| 2164 | } | |
| 2165 | } | |
| 2166 | } | |
| 2167 | ||
| 2124 | 2168 | fn writeBody(self: *Writer, stream: anytype, body: []const Zir.Inst.Index) !void { |
| 2125 | 2169 | for (body) |inst| { |
| 2126 | 2170 | try stream.writeByteNTimes(' ', self.indent); |
test/behavior/cast_llvm.zig+3-1| ... | ... | @@ -1,8 +1,9 @@ |
| 1 | const builtin = @import("builtin"); | |
| 1 | 2 | const std = @import("std"); |
| 2 | 3 | const expect = std.testing.expect; |
| 3 | 4 | const mem = std.mem; |
| 4 | 5 | const maxInt = std.math.maxInt; |
| 5 | const native_endian = @import("builtin").target.cpu.arch.endian(); | |
| 6 | const native_endian = builtin.target.cpu.arch.endian(); | |
| 6 | 7 | |
| 7 | 8 | test "pointer reinterpret const float to int" { |
| 8 | 9 | // The hex representation is 0x3fe3333333333303. |
| ... | ... | @@ -46,6 +47,7 @@ fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void { |
| 46 | 47 | } |
| 47 | 48 | |
| 48 | 49 | test "compile time int to ptr of function" { |
| 50 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) return error.SkipZigTest; // TODO | |
| 49 | 51 | try foobar(FUNCTION_CONSTANT); |
| 50 | 52 | } |
| 51 | 53 |
test/behavior/inttoptr.zig+3| ... | ... | @@ -1,4 +1,7 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | ||
| 1 | 3 | test "casting random address to function pointer" { |
| 4 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) return error.SkipZigTest; // TODO | |
| 2 | 5 | randomAddressToFunction(); |
| 3 | 6 | comptime randomAddressToFunction(); |
| 4 | 7 | } |