mirror of
https://github.com/ziglang/zig.git
synced 2026-02-15 13:58:27 +00:00
Merge pull request #12300 from antlilja/getParamName
Replace param_names and anytype_args fields inside of Fn with functions
This commit is contained in:
commit
42ade6a114
@ -1464,20 +1464,8 @@ pub const Fn = struct {
|
||||
/// These never have .generic_poison for the Type
|
||||
/// because the Type is needed to pass to `Type.eql` and for inserting comptime arguments
|
||||
/// into the inst_map when analyzing the body of a generic function instantiation.
|
||||
/// Instead, the is_anytype knowledge is communicated via `anytype_args`.
|
||||
/// Instead, the is_anytype knowledge is communicated via `isAnytypeParam`.
|
||||
comptime_args: ?[*]TypedValue,
|
||||
/// When comptime_args is null, this is undefined. Otherwise, this flags each
|
||||
/// parameter and tells whether it is anytype.
|
||||
/// TODO apply the same enhancement for param_names below to this field.
|
||||
anytype_args: [*]bool,
|
||||
|
||||
/// Prefer to use `getParamName` to access this because of the future improvement
|
||||
/// we want to do mentioned in the TODO below.
|
||||
/// Stored in gpa.
|
||||
/// TODO: change param ZIR instructions to be embedded inside the function
|
||||
/// ZIR instruction instead of before it, so that `zir_body_inst` can be used to
|
||||
/// determine param names rather than redundantly storing them here.
|
||||
param_names: []const [:0]const u8,
|
||||
|
||||
/// Precomputed hash for monomorphed_funcs.
|
||||
/// This is important because it may be accessed when resizing monomorphed_funcs
|
||||
@ -1590,18 +1578,43 @@ pub const Fn = struct {
|
||||
gpa.destroy(node);
|
||||
it = next;
|
||||
}
|
||||
|
||||
for (func.param_names) |param_name| {
|
||||
gpa.free(param_name);
|
||||
}
|
||||
gpa.free(func.param_names);
|
||||
}
|
||||
|
||||
pub fn getParamName(func: Fn, index: u32) [:0]const u8 {
|
||||
// TODO rework ZIR of parameters so that this function looks up
|
||||
// param names in ZIR instead of redundantly saving them into Fn.
|
||||
// const zir = func.owner_decl.getFileScope().zir;
|
||||
return func.param_names[index];
|
||||
pub fn isAnytypeParam(func: Fn, mod: *Module, index: u32) bool {
|
||||
const file = mod.declPtr(func.owner_decl).getFileScope();
|
||||
|
||||
const tags = file.zir.instructions.items(.tag);
|
||||
|
||||
const param_body = file.zir.getParamBody(func.zir_body_inst);
|
||||
const param = param_body[index];
|
||||
|
||||
return switch (tags[param]) {
|
||||
.param, .param_comptime => false,
|
||||
.param_anytype, .param_anytype_comptime => true,
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getParamName(func: Fn, mod: *Module, index: u32) [:0]const u8 {
|
||||
const file = mod.declPtr(func.owner_decl).getFileScope();
|
||||
|
||||
const tags = file.zir.instructions.items(.tag);
|
||||
const data = file.zir.instructions.items(.data);
|
||||
|
||||
const param_body = file.zir.getParamBody(func.zir_body_inst);
|
||||
const param = param_body[index];
|
||||
|
||||
return switch (tags[param]) {
|
||||
.param, .param_comptime => blk: {
|
||||
const extra = file.zir.extraData(Zir.Inst.Param, data[param].pl_tok.payload_index);
|
||||
break :blk file.zir.nullTerminatedString(extra.data.name);
|
||||
},
|
||||
.param_anytype, .param_anytype_comptime => blk: {
|
||||
const param_data = data[param].str_tok;
|
||||
break :blk param_data.get(file.zir);
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn hasInferredErrorSet(func: Fn, mod: *Module) bool {
|
||||
|
||||
17
src/Sema.zig
17
src/Sema.zig
@ -5506,7 +5506,7 @@ const GenericCallAdapter = struct {
|
||||
const this_is_comptime = this_arg.val.tag() != .generic_poison;
|
||||
const other_is_comptime = other_arg.val.tag() != .generic_poison;
|
||||
const this_is_anytype = this_arg.ty.tag() != .generic_poison;
|
||||
const other_is_anytype = other_key.anytype_args[i];
|
||||
const other_is_anytype = other_key.isAnytypeParam(ctx.module, @intCast(u32, i));
|
||||
|
||||
if (other_is_anytype != this_is_anytype) return false;
|
||||
if (other_is_comptime != this_is_comptime) return false;
|
||||
@ -6386,12 +6386,9 @@ fn instantiateGenericCall(
|
||||
errdefer new_func.deinit(gpa);
|
||||
assert(new_func == new_module_func);
|
||||
|
||||
const anytype_args = try new_decl_arena_allocator.alloc(bool, func_ty_info.param_types.len);
|
||||
new_func.anytype_args = anytype_args.ptr;
|
||||
arg_i = 0;
|
||||
for (fn_info.param_body) |inst| {
|
||||
var is_comptime = false;
|
||||
var is_anytype = false;
|
||||
switch (zir_tags[inst]) {
|
||||
.param => {
|
||||
is_comptime = func_ty_info.paramIsComptime(arg_i);
|
||||
@ -6400,11 +6397,9 @@ fn instantiateGenericCall(
|
||||
is_comptime = true;
|
||||
},
|
||||
.param_anytype => {
|
||||
is_anytype = true;
|
||||
is_comptime = func_ty_info.paramIsComptime(arg_i);
|
||||
},
|
||||
.param_anytype_comptime => {
|
||||
is_anytype = true;
|
||||
is_comptime = true;
|
||||
},
|
||||
else => continue,
|
||||
@ -6412,10 +6407,9 @@ fn instantiateGenericCall(
|
||||
|
||||
// We populate the Type here regardless because it is needed by
|
||||
// `GenericCallAdapter.eql` as well as function body analysis.
|
||||
// Whether it is anytype is communicated by `anytype_args`.
|
||||
// Whether it is anytype is communicated by `isAnytypeParam`.
|
||||
const arg = child_sema.inst_map.get(inst).?;
|
||||
const copied_arg_ty = try child_sema.typeOf(arg).copy(new_decl_arena_allocator);
|
||||
anytype_args[arg_i] = is_anytype;
|
||||
|
||||
if (try sema.typeRequiresComptime(block, .unneeded, copied_arg_ty)) {
|
||||
is_comptime = true;
|
||||
@ -7760,11 +7754,6 @@ fn funcCommon(
|
||||
break :blk if (sema.comptime_args.len == 0) null else sema.comptime_args.ptr;
|
||||
} else null;
|
||||
|
||||
const param_names = try sema.gpa.alloc([:0]const u8, block.params.items.len);
|
||||
for (param_names) |*param_name, i| {
|
||||
param_name.* = try sema.gpa.dupeZ(u8, block.params.items[i].name);
|
||||
}
|
||||
|
||||
const hash = new_func.hash;
|
||||
const fn_payload = try sema.arena.create(Value.Payload.Function);
|
||||
new_func.* = .{
|
||||
@ -7772,13 +7761,11 @@ fn funcCommon(
|
||||
.zir_body_inst = func_inst,
|
||||
.owner_decl = sema.owner_decl_index,
|
||||
.comptime_args = comptime_args,
|
||||
.anytype_args = undefined,
|
||||
.hash = hash,
|
||||
.lbrace_line = src_locs.lbrace_line,
|
||||
.rbrace_line = src_locs.rbrace_line,
|
||||
.lbrace_column = @truncate(u16, src_locs.columns),
|
||||
.rbrace_column = @truncate(u16, src_locs.columns >> 16),
|
||||
.param_names = param_names,
|
||||
.branch_quota = default_branch_quota,
|
||||
.is_noinline = is_noinline,
|
||||
};
|
||||
|
||||
21
src/Zir.zig
21
src/Zir.zig
@ -3915,6 +3915,27 @@ pub const FnInfo = struct {
|
||||
total_params_len: u32,
|
||||
};
|
||||
|
||||
pub fn getParamBody(zir: Zir, fn_inst: Inst.Index) []const u32 {
|
||||
const tags = zir.instructions.items(.tag);
|
||||
const datas = zir.instructions.items(.data);
|
||||
const inst_data = datas[fn_inst].pl_node;
|
||||
|
||||
const param_block_index = switch (tags[fn_inst]) {
|
||||
.func, .func_inferred => blk: {
|
||||
const extra = zir.extraData(Inst.Func, inst_data.payload_index);
|
||||
break :blk extra.data.param_block;
|
||||
},
|
||||
.func_fancy => blk: {
|
||||
const extra = zir.extraData(Inst.FuncFancy, inst_data.payload_index);
|
||||
break :blk extra.data.param_block;
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
const param_block = zir.extraData(Inst.Block, datas[param_block_index].pl_node.payload_index);
|
||||
return zir.extra[param_block.end..][0..param_block.data.body_len];
|
||||
}
|
||||
|
||||
pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo {
|
||||
const tags = zir.instructions.items(.tag);
|
||||
const datas = zir.instructions.items(.data);
|
||||
|
||||
@ -3372,7 +3372,7 @@ fn genArgDbgInfo(self: *Self, inst: Air.Inst.Index, arg_index: u32, stack_byte_c
|
||||
|
||||
const mcv = self.args[arg_index];
|
||||
const ty = self.air.instructions.items(.data)[inst].ty;
|
||||
const name = self.mod_fn.getParamName(arg_index);
|
||||
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg_index);
|
||||
const name_with_null = name.ptr[0 .. name.len + 1];
|
||||
|
||||
switch (mcv) {
|
||||
|
||||
@ -1619,7 +1619,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
|
||||
|
||||
fn genArgDbgInfo(self: *Self, inst: Air.Inst.Index, mcv: MCValue, arg_index: u32) !void {
|
||||
const ty = self.air.instructions.items(.data)[inst].ty;
|
||||
const name = self.mod_fn.getParamName(arg_index);
|
||||
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg_index);
|
||||
const name_with_null = name.ptr[0 .. name.len + 1];
|
||||
|
||||
switch (mcv) {
|
||||
|
||||
@ -2959,7 +2959,7 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
|
||||
|
||||
fn genArgDbgInfo(self: *Self, inst: Air.Inst.Index, mcv: MCValue, arg_index: u32) !void {
|
||||
const ty = self.air.instructions.items(.data)[inst].ty;
|
||||
const name = self.mod_fn.getParamName(arg_index);
|
||||
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg_index);
|
||||
const name_with_null = name.ptr[0 .. name.len + 1];
|
||||
|
||||
switch (mcv) {
|
||||
|
||||
@ -1991,7 +1991,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
|
||||
switch (self.debug_output) {
|
||||
.dwarf => |dwarf| {
|
||||
// TODO: Get the original arg index rather than wasm arg index
|
||||
const name = self.mod_fn.getParamName(arg_index);
|
||||
const name = self.mod_fn.getParamName(self.bin_file.base.options.module.?, arg_index);
|
||||
const leb_size = link.File.Wasm.getULEB128Size(arg.local);
|
||||
const dbg_info = &dwarf.dbg_info;
|
||||
try dbg_info.ensureUnusedCapacity(3 + leb_size + 5 + name.len + 1);
|
||||
|
||||
@ -3789,7 +3789,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
|
||||
|
||||
const ty = self.air.typeOfIndex(inst);
|
||||
const mcv = self.args[arg_index];
|
||||
const name = self.mod_fn.getParamName(arg_index);
|
||||
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg_index);
|
||||
const name_with_null = name.ptr[0 .. name.len + 1];
|
||||
|
||||
if (self.liveness.isUnused(inst))
|
||||
|
||||
@ -7313,7 +7313,7 @@ pub const FuncGen = struct {
|
||||
const lbrace_col = func.lbrace_column + 1;
|
||||
const di_local_var = dib.createParameterVariable(
|
||||
self.di_scope.?,
|
||||
func.getParamName(src_index).ptr, // TODO test 0 bit args
|
||||
func.getParamName(self.dg.module, src_index).ptr, // TODO test 0 bit args
|
||||
self.di_file.?,
|
||||
lbrace_line,
|
||||
try self.dg.object.lowerDebugType(inst_ty, .full),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user