mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
Merge pull request #10662 from ziglang/doc-comments-zir
Doc comments zir
This commit is contained in:
commit
12c2de6ee2
@ -26,7 +26,9 @@ comptime {
|
||||
if (builtin.zig_backend == .stage1) {
|
||||
_ = @import("compiler_rt/atomics.zig");
|
||||
}
|
||||
_ = @import("compiler_rt/clear_cache.zig").clear_cache;
|
||||
if (builtin.zig_backend != .stage2_llvm) { // TODO
|
||||
_ = @import("compiler_rt/clear_cache.zig").clear_cache;
|
||||
}
|
||||
|
||||
const __extenddftf2 = @import("compiler_rt/extendXfYf2.zig").__extenddftf2;
|
||||
@export(__extenddftf2, .{ .name = "__extenddftf2", .linkage = linkage });
|
||||
|
||||
@ -2120,6 +2120,14 @@ pub const full = struct {
|
||||
section_node: Node.Index,
|
||||
init_node: Node.Index,
|
||||
};
|
||||
|
||||
pub fn firstToken(var_decl: VarDecl) TokenIndex {
|
||||
return var_decl.visib_token orelse
|
||||
var_decl.extern_export_token orelse
|
||||
var_decl.threadlocal_token orelse
|
||||
var_decl.comptime_token orelse
|
||||
var_decl.ast.mut_token;
|
||||
}
|
||||
};
|
||||
|
||||
pub const If = struct {
|
||||
@ -2168,6 +2176,10 @@ pub const full = struct {
|
||||
value_expr: Node.Index,
|
||||
align_expr: Node.Index,
|
||||
};
|
||||
|
||||
pub fn firstToken(cf: ContainerField) TokenIndex {
|
||||
return cf.comptime_token orelse cf.ast.name_token;
|
||||
}
|
||||
};
|
||||
|
||||
pub const FnProto = struct {
|
||||
@ -2197,6 +2209,12 @@ pub const full = struct {
|
||||
type_expr: Node.Index,
|
||||
};
|
||||
|
||||
pub fn firstToken(fn_proto: FnProto) TokenIndex {
|
||||
return fn_proto.visib_token orelse
|
||||
fn_proto.extern_export_inline_token orelse
|
||||
fn_proto.ast.fn_token;
|
||||
}
|
||||
|
||||
/// Abstracts over the fact that anytype and ... are not included
|
||||
/// in the params slice, since they are simple identifiers and
|
||||
/// not sub-expressions.
|
||||
|
||||
113
src/AstGen.zig
113
src/AstGen.zig
@ -1171,7 +1171,7 @@ fn fnProtoExpr(
|
||||
const main_tokens = tree.nodes.items(.main_token);
|
||||
const name_token = param.name_token orelse main_tokens[param_type_node];
|
||||
const tag: Zir.Inst.Tag = if (is_comptime) .param_comptime else .param;
|
||||
const param_inst = try block_scope.addParam(¶m_gz, tag, name_token, param_name);
|
||||
const param_inst = try block_scope.addParam(¶m_gz, tag, name_token, param_name, param.first_doc_comment);
|
||||
assert(param_inst_expected == param_inst);
|
||||
}
|
||||
}
|
||||
@ -3080,9 +3080,9 @@ const WipMembers = struct {
|
||||
/// struct, union, enum, and opaque decls all use same 4 bits per decl
|
||||
const bits_per_decl = 4;
|
||||
const decls_per_u32 = 32 / bits_per_decl;
|
||||
/// struct, union, enum, and opaque decls all have maximum size of 10 u32 slots
|
||||
/// (4 for src_hash + line + name + value + align + link_section + address_space)
|
||||
const max_decl_size = 10;
|
||||
/// struct, union, enum, and opaque decls all have maximum size of 11 u32 slots
|
||||
/// (4 for src_hash + line + name + value + doc_comment + align + link_section + address_space )
|
||||
const max_decl_size = 11;
|
||||
|
||||
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 {
|
||||
const payload_top = @intCast(u32, payload.items.len);
|
||||
@ -3236,6 +3236,9 @@ fn fnDecl(
|
||||
const maybe_inline_token = fn_proto.extern_export_inline_token orelse break :blk false;
|
||||
break :blk token_tags[maybe_inline_token] == .keyword_inline;
|
||||
};
|
||||
|
||||
const doc_comment_index = try astgen.docCommentAsString(fn_proto.firstToken());
|
||||
|
||||
const has_section_or_addrspace = fn_proto.ast.section_expr != 0 or fn_proto.ast.addrspace_expr != 0;
|
||||
wip_members.nextDecl(is_pub, is_export, fn_proto.ast.align_expr != 0, has_section_or_addrspace);
|
||||
|
||||
@ -3294,7 +3297,7 @@ fn fnDecl(
|
||||
const main_tokens = tree.nodes.items(.main_token);
|
||||
const name_token = param.name_token orelse main_tokens[param_type_node];
|
||||
const tag: Zir.Inst.Tag = if (is_comptime) .param_comptime else .param;
|
||||
const param_inst = try decl_gz.addParam(¶m_gz, tag, name_token, param_name);
|
||||
const param_inst = try decl_gz.addParam(¶m_gz, tag, name_token, param_name, param.first_doc_comment);
|
||||
assert(param_inst_expected == param_inst);
|
||||
break :param indexToRef(param_inst);
|
||||
};
|
||||
@ -3445,6 +3448,7 @@ fn fnDecl(
|
||||
}
|
||||
wip_members.appendToDecl(fn_name_str_index);
|
||||
wip_members.appendToDecl(block_inst);
|
||||
wip_members.appendToDecl(doc_comment_index);
|
||||
if (align_inst != .none) {
|
||||
wip_members.appendToDecl(@enumToInt(align_inst));
|
||||
}
|
||||
@ -3519,6 +3523,8 @@ fn globalVarDecl(
|
||||
break :blk lib_name_str.index;
|
||||
} else 0;
|
||||
|
||||
const doc_comment_index = try astgen.docCommentAsString(var_decl.firstToken());
|
||||
|
||||
assert(var_decl.comptime_token == null); // handled by parser
|
||||
|
||||
const var_inst: Zir.Inst.Ref = if (var_decl.ast.init_node != 0) vi: {
|
||||
@ -3594,6 +3600,7 @@ fn globalVarDecl(
|
||||
}
|
||||
wip_members.appendToDecl(name_str_index);
|
||||
wip_members.appendToDecl(block_inst);
|
||||
wip_members.appendToDecl(doc_comment_index); // doc_comment wip
|
||||
if (align_inst != .none) {
|
||||
wip_members.appendToDecl(@enumToInt(align_inst));
|
||||
}
|
||||
@ -3648,6 +3655,7 @@ fn comptimeDecl(
|
||||
}
|
||||
wip_members.appendToDecl(0);
|
||||
wip_members.appendToDecl(block_inst);
|
||||
wip_members.appendToDecl(0); // no doc comments on comptime decls
|
||||
}
|
||||
|
||||
fn usingnamespaceDecl(
|
||||
@ -3699,6 +3707,7 @@ fn usingnamespaceDecl(
|
||||
}
|
||||
wip_members.appendToDecl(0);
|
||||
wip_members.appendToDecl(block_inst);
|
||||
wip_members.appendToDecl(0); // no doc comments on usingnamespace decls
|
||||
}
|
||||
|
||||
fn testDecl(
|
||||
@ -3802,6 +3811,7 @@ fn testDecl(
|
||||
}
|
||||
wip_members.appendToDecl(test_name);
|
||||
wip_members.appendToDecl(block_inst);
|
||||
wip_members.appendToDecl(0); // no doc comments on test decls
|
||||
}
|
||||
|
||||
fn structDeclInner(
|
||||
@ -3857,7 +3867,7 @@ fn structDeclInner(
|
||||
const field_count = @intCast(u32, container_decl.ast.members.len - decl_count);
|
||||
|
||||
const bits_per_field = 4;
|
||||
const max_field_size = 4;
|
||||
const max_field_size = 5;
|
||||
var wip_members = try WipMembers.init(gpa, &astgen.scratch, decl_count, field_count, bits_per_field, max_field_size);
|
||||
defer wip_members.deinit();
|
||||
|
||||
@ -3881,6 +3891,9 @@ fn structDeclInner(
|
||||
try typeExpr(&block_scope, &namespace.base, member.ast.type_expr);
|
||||
wip_members.appendToField(@enumToInt(field_type));
|
||||
|
||||
const doc_comment_index = try astgen.docCommentAsString(member.firstToken());
|
||||
wip_members.appendToField(doc_comment_index);
|
||||
|
||||
known_has_bits = known_has_bits or nodeImpliesRuntimeBits(tree, member.ast.type_expr);
|
||||
|
||||
const have_align = member.ast.align_expr != 0;
|
||||
@ -3979,7 +3992,7 @@ fn unionDeclInner(
|
||||
.none;
|
||||
|
||||
const bits_per_field = 4;
|
||||
const max_field_size = 4;
|
||||
const max_field_size = 5;
|
||||
var wip_members = try WipMembers.init(gpa, &astgen.scratch, decl_count, field_count, bits_per_field, max_field_size);
|
||||
defer wip_members.deinit();
|
||||
|
||||
@ -3995,6 +4008,9 @@ fn unionDeclInner(
|
||||
const field_name = try astgen.identAsString(member.ast.name_token);
|
||||
wip_members.appendToField(field_name);
|
||||
|
||||
const doc_comment_index = try astgen.docCommentAsString(member.firstToken());
|
||||
wip_members.appendToField(doc_comment_index);
|
||||
|
||||
const have_type = member.ast.type_expr != 0;
|
||||
const have_align = member.ast.align_expr != 0;
|
||||
const have_value = member.ast.value_expr != 0;
|
||||
@ -4258,7 +4274,7 @@ fn containerDecl(
|
||||
.none;
|
||||
|
||||
const bits_per_field = 1;
|
||||
const max_field_size = 2;
|
||||
const max_field_size = 3;
|
||||
var wip_members = try WipMembers.init(gpa, &astgen.scratch, @intCast(u32, counts.decls), @intCast(u32, counts.total_fields), bits_per_field, max_field_size);
|
||||
defer wip_members.deinit();
|
||||
|
||||
@ -4276,6 +4292,9 @@ fn containerDecl(
|
||||
const field_name = try astgen.identAsString(member.ast.name_token);
|
||||
wip_members.appendToField(field_name);
|
||||
|
||||
const doc_comment_index = try astgen.docCommentAsString(member.firstToken());
|
||||
wip_members.appendToField(doc_comment_index);
|
||||
|
||||
const have_value = member.ast.value_expr != 0;
|
||||
wip_members.nextField(bits_per_field, .{have_value});
|
||||
|
||||
@ -4506,8 +4525,11 @@ fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir
|
||||
switch (token_tags[tok_i]) {
|
||||
.doc_comment, .comma => {},
|
||||
.identifier => {
|
||||
try astgen.extra.ensureUnusedCapacity(gpa, 2);
|
||||
const str_index = try astgen.identAsString(tok_i);
|
||||
try astgen.extra.append(gpa, str_index);
|
||||
astgen.extra.appendAssumeCapacity(str_index);
|
||||
const doc_comment_index = try astgen.docCommentAsString(tok_i);
|
||||
astgen.extra.appendAssumeCapacity(doc_comment_index);
|
||||
fields_len += 1;
|
||||
},
|
||||
.r_brace => break,
|
||||
@ -8784,6 +8806,72 @@ fn identAsString(astgen: *AstGen, ident_token: Ast.TokenIndex) !u32 {
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds a doc comment block to `string_bytes` by walking backwards from `end_token`.
|
||||
/// `end_token` must point at the first token after the last doc coment line.
|
||||
/// Returns 0 if no doc comment is present.
|
||||
fn docCommentAsString(astgen: *AstGen, end_token: Ast.TokenIndex) !u32 {
|
||||
if (end_token == 0) return @as(u32, 0);
|
||||
|
||||
const token_tags = astgen.tree.tokens.items(.tag);
|
||||
|
||||
var tok = end_token - 1;
|
||||
while (token_tags[tok] == .doc_comment) {
|
||||
if (tok == 0) break;
|
||||
tok -= 1;
|
||||
} else {
|
||||
tok += 1;
|
||||
}
|
||||
return docCommentAsStringFromFirst(astgen, end_token, tok);
|
||||
}
|
||||
|
||||
/// end_token must be > the index of the last doc comment.
|
||||
fn docCommentAsStringFromFirst(
|
||||
astgen: *AstGen,
|
||||
end_token: Ast.TokenIndex,
|
||||
start_token: Ast.TokenIndex,
|
||||
) !u32 {
|
||||
if (start_token == end_token) return 0;
|
||||
|
||||
const gpa = astgen.gpa;
|
||||
const string_bytes = &astgen.string_bytes;
|
||||
const str_index = @intCast(u32, string_bytes.items.len);
|
||||
const token_starts = astgen.tree.tokens.items(.start);
|
||||
const token_tags = astgen.tree.tokens.items(.tag);
|
||||
|
||||
const total_bytes = token_starts[end_token] - token_starts[start_token];
|
||||
try string_bytes.ensureUnusedCapacity(gpa, total_bytes);
|
||||
|
||||
var current_token = start_token;
|
||||
while (current_token < end_token) : (current_token += 1) {
|
||||
switch (token_tags[current_token]) {
|
||||
.doc_comment => {
|
||||
const tok_bytes = astgen.tree.tokenSlice(current_token)[3..];
|
||||
string_bytes.appendSliceAssumeCapacity(tok_bytes);
|
||||
if (current_token != end_token - 1) {
|
||||
string_bytes.appendAssumeCapacity('\n');
|
||||
}
|
||||
},
|
||||
else => break,
|
||||
}
|
||||
}
|
||||
|
||||
const key = string_bytes.items[str_index..];
|
||||
const gop = try astgen.string_table.getOrPutContextAdapted(gpa, @as([]const u8, key), StringIndexAdapter{
|
||||
.bytes = string_bytes,
|
||||
}, StringIndexContext{
|
||||
.bytes = string_bytes,
|
||||
});
|
||||
|
||||
if (gop.found_existing) {
|
||||
string_bytes.shrinkRetainingCapacity(str_index);
|
||||
return gop.key_ptr.*;
|
||||
} else {
|
||||
gop.key_ptr.* = str_index;
|
||||
try string_bytes.append(gpa, 0);
|
||||
return str_index;
|
||||
}
|
||||
}
|
||||
|
||||
const IndexSlice = struct { index: u32, len: u32 };
|
||||
|
||||
fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice {
|
||||
@ -9629,6 +9717,7 @@ const GenZir = struct {
|
||||
/// Absolute token index. This function does the conversion to Decl offset.
|
||||
abs_tok_index: Ast.TokenIndex,
|
||||
name: u32,
|
||||
first_doc_comment: ?Ast.TokenIndex,
|
||||
) !Zir.Inst.Index {
|
||||
const gpa = gz.astgen.gpa;
|
||||
const param_body = param_gz.instructionsSlice();
|
||||
@ -9636,8 +9725,14 @@ const GenZir = struct {
|
||||
try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.Param).Struct.fields.len +
|
||||
param_body.len);
|
||||
|
||||
const doc_comment_index = if (first_doc_comment) |first|
|
||||
try gz.astgen.docCommentAsStringFromFirst(abs_tok_index, first)
|
||||
else
|
||||
0;
|
||||
|
||||
const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Param{
|
||||
.name = name,
|
||||
.doc_comment = doc_comment_index,
|
||||
.body_len = @intCast(u32, param_body.len),
|
||||
});
|
||||
gz.astgen.extra.appendSliceAssumeCapacity(param_body);
|
||||
|
||||
@ -558,14 +558,14 @@ pub const Decl = struct {
|
||||
if (!decl.has_align) return .none;
|
||||
assert(decl.zir_decl_index != 0);
|
||||
const zir = decl.getFileScope().zir;
|
||||
return @intToEnum(Zir.Inst.Ref, zir.extra[decl.zir_decl_index + 7]);
|
||||
return @intToEnum(Zir.Inst.Ref, zir.extra[decl.zir_decl_index + 8]);
|
||||
}
|
||||
|
||||
pub fn zirLinksectionRef(decl: Decl) Zir.Inst.Ref {
|
||||
if (!decl.has_linksection_or_addrspace) return .none;
|
||||
assert(decl.zir_decl_index != 0);
|
||||
const zir = decl.getFileScope().zir;
|
||||
const extra_index = decl.zir_decl_index + 7 + @boolToInt(decl.has_align);
|
||||
const extra_index = decl.zir_decl_index + 8 + @boolToInt(decl.has_align);
|
||||
return @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);
|
||||
}
|
||||
|
||||
@ -573,7 +573,7 @@ pub const Decl = struct {
|
||||
if (!decl.has_linksection_or_addrspace) return .none;
|
||||
assert(decl.zir_decl_index != 0);
|
||||
const zir = decl.getFileScope().zir;
|
||||
const extra_index = decl.zir_decl_index + 7 + @boolToInt(decl.has_align) + 1;
|
||||
const extra_index = decl.zir_decl_index + 8 + @boolToInt(decl.has_align) + 1;
|
||||
return @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);
|
||||
}
|
||||
|
||||
@ -4011,7 +4011,7 @@ pub fn scanNamespace(
|
||||
cur_bit_bag >>= 4;
|
||||
|
||||
const decl_sub_index = extra_index;
|
||||
extra_index += 7; // src_hash(4) + line(1) + name(1) + value(1)
|
||||
extra_index += 8; // src_hash(4) + line(1) + name(1) + value(1) + doc_comment(1)
|
||||
extra_index += @truncate(u1, flags >> 2); // Align
|
||||
extra_index += @as(u2, @truncate(u1, flags >> 3)) * 2; // Link section or address space, consists of 2 Refs
|
||||
|
||||
|
||||
18
src/Sema.zig
18
src/Sema.zig
@ -1916,6 +1916,9 @@ fn zirEnumDecl(
|
||||
const field_name_zir = sema.code.nullTerminatedString(sema.code.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
|
||||
// doc comment
|
||||
extra_index += 1;
|
||||
|
||||
// This string needs to outlive the ZIR code.
|
||||
const field_name = try new_decl_arena_allocator.dupe(u8, field_name_zir);
|
||||
|
||||
@ -2103,7 +2106,6 @@ fn zirErrorSetDecl(
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
|
||||
const src = inst_data.src();
|
||||
const extra = sema.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index);
|
||||
const fields = sema.code.extra[extra.end..][0..extra.data.fields_len];
|
||||
|
||||
var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
|
||||
errdefer new_decl_arena.deinit();
|
||||
@ -2121,8 +2123,12 @@ fn zirErrorSetDecl(
|
||||
errdefer sema.mod.abortAnonDecl(new_decl);
|
||||
|
||||
var names = Module.ErrorSet.NameMap{};
|
||||
try names.ensureUnusedCapacity(new_decl_arena_allocator, fields.len);
|
||||
for (fields) |str_index| {
|
||||
try names.ensureUnusedCapacity(new_decl_arena_allocator, extra.data.fields_len);
|
||||
|
||||
var extra_index = @intCast(u32, extra.end);
|
||||
const extra_index_end = extra_index + (extra.data.fields_len * 2);
|
||||
while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string
|
||||
const str_index = sema.code.extra[extra_index];
|
||||
const name = try new_decl_arena_allocator.dupe(u8, sema.code.nullTerminatedString(str_index));
|
||||
|
||||
// TODO: This check should be performed in AstGen instead.
|
||||
@ -16313,6 +16319,9 @@ fn semaStructFields(
|
||||
const field_type_ref = @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
|
||||
// doc_comment
|
||||
extra_index += 1;
|
||||
|
||||
// This string needs to outlive the ZIR code.
|
||||
const field_name = try decl_arena_allocator.dupe(u8, field_name_zir);
|
||||
const field_ty: Type = if (field_type_ref == .none)
|
||||
@ -16502,6 +16511,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
|
||||
const field_name_zir = zir.nullTerminatedString(zir.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
|
||||
// doc_comment
|
||||
extra_index += 1;
|
||||
|
||||
const field_type_ref: Zir.Inst.Ref = if (has_type) blk: {
|
||||
const field_type_ref = @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
|
||||
17
src/Zir.zig
17
src/Zir.zig
@ -2571,6 +2571,7 @@ pub const Inst = struct {
|
||||
/// - if there is a 0 byte at the position `name` indexes, it indicates
|
||||
/// this is a test decl, and the name starts at `name+1`.
|
||||
/// value: Index,
|
||||
/// doc_comment: u32, // 0 if no doc comment
|
||||
/// align: Ref, // if corresponding bit is set
|
||||
/// link_section_or_address_space: { // if corresponding bit is set.
|
||||
/// link_section: Ref,
|
||||
@ -2588,6 +2589,7 @@ pub const Inst = struct {
|
||||
/// field_name: u32,
|
||||
/// field_type: Ref,
|
||||
/// - if none, means `anytype`.
|
||||
/// doc_comment: u32, // 0 if no doc comment
|
||||
/// align: Ref, // if corresponding bit is set
|
||||
/// default_value: Ref, // if corresponding bit is set
|
||||
/// }
|
||||
@ -2638,6 +2640,7 @@ pub const Inst = struct {
|
||||
/// - if there is a 0 byte at the position `name` indexes, it indicates
|
||||
/// this is a test decl, and the name starts at `name+1`.
|
||||
/// value: Index,
|
||||
/// doc_comment: u32, // 0 if no doc_comment
|
||||
/// align: Ref, // if corresponding bit is set
|
||||
/// link_section_or_address_space: { // if corresponding bit is set.
|
||||
/// link_section: Ref,
|
||||
@ -2649,6 +2652,7 @@ pub const Inst = struct {
|
||||
/// - the bit is whether corresponding field has an value expression
|
||||
/// 9. fields: { // for every fields_len
|
||||
/// field_name: u32,
|
||||
/// doc_comment: u32, // 0 if no doc_comment
|
||||
/// value: Ref, // if corresponding bit is set
|
||||
/// }
|
||||
pub const EnumDecl = struct {
|
||||
@ -2686,6 +2690,7 @@ pub const Inst = struct {
|
||||
/// - if there is a 0 byte at the position `name` indexes, it indicates
|
||||
/// this is a test decl, and the name starts at `name+1`.
|
||||
/// value: Index,
|
||||
/// doc_comment: u32, // 0 if no doc comment
|
||||
/// align: Ref, // if corresponding bit is set
|
||||
/// link_section_or_address_space: { // if corresponding bit is set.
|
||||
/// link_section: Ref,
|
||||
@ -2701,6 +2706,7 @@ pub const Inst = struct {
|
||||
/// 0bX000: unused
|
||||
/// 9. fields: { // for every fields_len
|
||||
/// field_name: u32, // null terminated string index
|
||||
/// doc_comment: u32, // 0 if no doc comment
|
||||
/// field_type: Ref, // if corresponding bit is set
|
||||
/// - if none, means `anytype`.
|
||||
/// align: Ref, // if corresponding bit is set
|
||||
@ -2745,6 +2751,7 @@ pub const Inst = struct {
|
||||
/// - if there is a 0 byte at the position `name` indexes, it indicates
|
||||
/// this is a test decl, and the name starts at `name+1`.
|
||||
/// value: Index,
|
||||
/// doc_comment: u32, // 0 if no doc comment,
|
||||
/// align: Ref, // if corresponding bit is set
|
||||
/// link_section_or_address_space: { // if corresponding bit is set.
|
||||
/// link_section: Ref,
|
||||
@ -2760,7 +2767,11 @@ pub const Inst = struct {
|
||||
};
|
||||
};
|
||||
|
||||
/// Trailing: field_name: u32 // for every field: null terminated string index
|
||||
/// Trailing:
|
||||
/// { // for every fields_len
|
||||
/// field_name: u32 // null terminated string index
|
||||
/// doc_comment: u32 // null terminated string index
|
||||
/// }
|
||||
pub const ErrorSetDecl = struct {
|
||||
fields_len: u32,
|
||||
};
|
||||
@ -2899,6 +2910,8 @@ pub const Inst = struct {
|
||||
pub const Param = struct {
|
||||
/// Null-terminated string index.
|
||||
name: u32,
|
||||
/// 0 if no doc comment
|
||||
doc_comment: u32,
|
||||
/// The body contains the type of the parameter.
|
||||
body_len: u32,
|
||||
};
|
||||
@ -3001,7 +3014,7 @@ pub const DeclIterator = struct {
|
||||
const sub_index = @intCast(u32, it.extra_index);
|
||||
it.extra_index += 5; // src_hash(4) + line(1)
|
||||
const name = it.zir.nullTerminatedString(it.zir.extra[it.extra_index]);
|
||||
it.extra_index += 2; // name(1) + value(1)
|
||||
it.extra_index += 3; // name(1) + value(1) + doc_comment(1)
|
||||
it.extra_index += @truncate(u1, flags >> 2);
|
||||
it.extra_index += @truncate(u1, flags >> 3);
|
||||
|
||||
|
||||
@ -785,6 +785,12 @@ const Writer = struct {
|
||||
try stream.print("\"{}\", ", .{
|
||||
std.zig.fmtEscapes(self.code.nullTerminatedString(extra.data.name)),
|
||||
});
|
||||
|
||||
if (extra.data.doc_comment != 0) {
|
||||
try stream.writeAll("\n");
|
||||
try self.writeDocComment(stream, extra.data.doc_comment);
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
}
|
||||
try self.writeBracedBody(stream, body);
|
||||
try stream.writeAll(") ");
|
||||
try self.writeSrc(stream, inst_data.src());
|
||||
@ -1207,6 +1213,10 @@ const Writer = struct {
|
||||
extra_index += 1;
|
||||
const field_type = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
const doc_comment_index = self.code.extra[extra_index];
|
||||
extra_index += 1;
|
||||
|
||||
try self.writeDocComment(stream, doc_comment_index);
|
||||
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try self.writeFlag(stream, "comptime ", is_comptime);
|
||||
@ -1332,6 +1342,10 @@ const Writer = struct {
|
||||
|
||||
const field_name = self.code.nullTerminatedString(self.code.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
const doc_comment_index = self.code.extra[extra_index];
|
||||
extra_index += 1;
|
||||
|
||||
try self.writeDocComment(stream, doc_comment_index);
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try stream.print("{}", .{std.zig.fmtId(field_name)});
|
||||
|
||||
@ -1398,6 +1412,9 @@ const Writer = struct {
|
||||
extra_index += 1;
|
||||
const decl_index = self.code.extra[extra_index];
|
||||
extra_index += 1;
|
||||
const doc_comment_index = self.code.extra[extra_index];
|
||||
extra_index += 1;
|
||||
|
||||
const align_inst: Zir.Inst.Ref = if (!has_align) .none else inst: {
|
||||
const inst = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
@ -1416,12 +1433,13 @@ const Writer = struct {
|
||||
|
||||
const pub_str = if (is_pub) "pub " else "";
|
||||
const hash_bytes = @bitCast([16]u8, hash_u32s.*);
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
if (decl_name_index == 0) {
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
const name = if (is_exported) "usingnamespace" else "comptime";
|
||||
try stream.writeAll(pub_str);
|
||||
try stream.writeAll(name);
|
||||
} else if (decl_name_index == 1) {
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try stream.writeAll("test");
|
||||
} else {
|
||||
const raw_decl_name = self.code.nullTerminatedString(decl_name_index);
|
||||
@ -1431,6 +1449,10 @@ const Writer = struct {
|
||||
raw_decl_name;
|
||||
const test_str = if (raw_decl_name.len == 0) "test " else "";
|
||||
const export_str = if (is_exported) "export " else "";
|
||||
|
||||
try self.writeDocComment(stream, doc_comment_index);
|
||||
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try stream.print("[{d}] {s}{s}{s}{}", .{
|
||||
sub_index, pub_str, test_str, export_str, std.zig.fmtId(decl_name),
|
||||
});
|
||||
@ -1556,6 +1578,11 @@ const Writer = struct {
|
||||
const field_name = self.code.nullTerminatedString(self.code.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
|
||||
const doc_comment_index = self.code.extra[extra_index];
|
||||
extra_index += 1;
|
||||
|
||||
try self.writeDocComment(stream, doc_comment_index);
|
||||
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try stream.print("{}", .{std.zig.fmtId(field_name)});
|
||||
|
||||
@ -1619,17 +1646,23 @@ const Writer = struct {
|
||||
) !void {
|
||||
const inst_data = self.code.instructions.items(.data)[inst].pl_node;
|
||||
const extra = self.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index);
|
||||
const fields = self.code.extra[extra.end..][0..extra.data.fields_len];
|
||||
|
||||
try stream.print("{s}, ", .{@tagName(name_strategy)});
|
||||
|
||||
try stream.writeAll("{\n");
|
||||
self.indent += 2;
|
||||
for (fields) |str_index| {
|
||||
|
||||
var extra_index = @intCast(u32, extra.end);
|
||||
const extra_index_end = extra_index + (extra.data.fields_len * 2);
|
||||
while (extra_index < extra_index_end) : (extra_index += 2) {
|
||||
const str_index = self.code.extra[extra_index];
|
||||
const name = self.code.nullTerminatedString(str_index);
|
||||
const doc_comment_index = self.code.extra[extra_index + 1];
|
||||
try self.writeDocComment(stream, doc_comment_index);
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try stream.print("{},\n", .{std.zig.fmtId(name)});
|
||||
}
|
||||
|
||||
self.indent -= 2;
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try stream.writeAll("}) ");
|
||||
@ -2121,6 +2154,17 @@ const Writer = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn writeDocComment(self: *Writer, stream: anytype, doc_comment_index: u32) !void {
|
||||
if (doc_comment_index != 0) {
|
||||
const doc_comment = self.code.nullTerminatedString(doc_comment_index);
|
||||
var it = std.mem.tokenize(u8, doc_comment, "\n");
|
||||
while (it.next()) |doc_line| {
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try stream.print("///{s}\n", .{doc_line});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn writeBody(self: *Writer, stream: anytype, body: []const Zir.Inst.Index) !void {
|
||||
for (body) |inst| {
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
const builtin = @import("builtin");
|
||||
const std = @import("std");
|
||||
const expect = std.testing.expect;
|
||||
const mem = std.mem;
|
||||
const maxInt = std.math.maxInt;
|
||||
const native_endian = @import("builtin").target.cpu.arch.endian();
|
||||
const native_endian = builtin.target.cpu.arch.endian();
|
||||
|
||||
test "pointer reinterpret const float to int" {
|
||||
// The hex representation is 0x3fe3333333333303.
|
||||
@ -46,6 +47,7 @@ fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void {
|
||||
}
|
||||
|
||||
test "compile time int to ptr of function" {
|
||||
if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) return error.SkipZigTest; // TODO
|
||||
try foobar(FUNCTION_CONSTANT);
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
const builtin = @import("builtin");
|
||||
|
||||
test "casting random address to function pointer" {
|
||||
if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) return error.SkipZigTest; // TODO
|
||||
randomAddressToFunction();
|
||||
comptime randomAddressToFunction();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user