aboutsummaryrefslogtreecommitdiff
path: root/src/Module.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/Module.zig')
-rw-r--r--src/Module.zig60
1 files changed, 57 insertions, 3 deletions
diff --git a/src/Module.zig b/src/Module.zig
index 1e684f6ea1..8bb5a94c17 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -5939,10 +5939,11 @@ pub fn argSrc(
call_node_offset: i32,
gpa: Allocator,
decl: *Decl,
- arg_i: usize,
+ start_arg_i: usize,
bound_arg_src: ?LazySrcLoc,
) LazySrcLoc {
- if (arg_i == 0 and bound_arg_src != null) return bound_arg_src.?;
+ if (start_arg_i == 0 and bound_arg_src != null) return bound_arg_src.?;
+ const arg_i = start_arg_i - @boolToInt(bound_arg_src != null);
@setCold(true);
const tree = decl.getFileScope().getTree(gpa) catch |err| {
// In this case we emit a warning + a less precise source location.
@@ -5957,6 +5958,12 @@ pub fn argSrc(
const full = switch (node_tags[node]) {
.call_one, .call_one_comma, .async_call_one, .async_call_one_comma => tree.callOne(&args, node),
.call, .call_comma, .async_call, .async_call_comma => tree.callFull(node),
+ .builtin_call => {
+ const node_datas = tree.nodes.items(.data);
+ const call_args_node = tree.extra_data[node_datas[node].rhs - 1];
+ const call_args_offset = decl.nodeIndexToRelative(call_args_node);
+ return initSrc(call_args_offset, gpa, decl, arg_i);
+ },
else => unreachable,
};
return LazySrcLoc.nodeOffset(decl.nodeIndexToRelative(full.ast.params[arg_i]));
@@ -5989,7 +5996,7 @@ pub fn initSrc(
.struct_init_dot_two, .struct_init_dot_two_comma => tree.structInitDotTwo(&buf, node).ast.fields,
.struct_init_dot, .struct_init_dot_comma => tree.structInitDot(node).ast.fields,
.struct_init, .struct_init_comma => tree.structInit(node).ast.fields,
- else => unreachable,
+ else => return LazySrcLoc.nodeOffset(init_node_offset),
};
switch (node_tags[node]) {
.array_init_one,
@@ -6014,6 +6021,53 @@ pub fn initSrc(
}
}
+pub fn optionsSrc(gpa: Allocator, decl: *Decl, base_src: LazySrcLoc, wanted: []const u8) LazySrcLoc {
+ @setCold(true);
+ const tree = decl.getFileScope().getTree(gpa) catch |err| {
+ // In this case we emit a warning + a less precise source location.
+ log.warn("unable to load {s}: {s}", .{
+ decl.getFileScope().sub_file_path, @errorName(err),
+ });
+ return LazySrcLoc.nodeOffset(0);
+ };
+
+ const o_i: struct { off: i32, i: u8 } = switch (base_src) {
+ .node_offset_builtin_call_arg0 => |n| .{ .off = n, .i = 0 },
+ .node_offset_builtin_call_arg1 => |n| .{ .off = n, .i = 1 },
+ else => unreachable,
+ };
+
+ const node = decl.relativeToNodeIndex(o_i.off);
+ const node_datas = tree.nodes.items(.data);
+ const node_tags = tree.nodes.items(.tag);
+ const arg_node = switch (node_tags[node]) {
+ .builtin_call_two, .builtin_call_two_comma => switch (o_i.i) {
+ 0 => node_datas[node].lhs,
+ 1 => node_datas[node].rhs,
+ else => unreachable,
+ },
+ .builtin_call, .builtin_call_comma => tree.extra_data[node_datas[node].lhs + o_i.i],
+ else => unreachable,
+ };
+ var buf: [2]std.zig.Ast.Node.Index = undefined;
+ const init_nodes = switch (node_tags[arg_node]) {
+ .struct_init_one, .struct_init_one_comma => tree.structInitOne(buf[0..1], arg_node).ast.fields,
+ .struct_init_dot_two, .struct_init_dot_two_comma => tree.structInitDotTwo(&buf, arg_node).ast.fields,
+ .struct_init_dot, .struct_init_dot_comma => tree.structInitDot(arg_node).ast.fields,
+ .struct_init, .struct_init_comma => tree.structInit(arg_node).ast.fields,
+ else => return base_src,
+ };
+ for (init_nodes) |init_node| {
+ // . IDENTIFIER = init_node
+ const name_token = tree.firstToken(init_node) - 2;
+ const name = tree.tokenSlice(name_token);
+ if (std.mem.eql(u8, name, wanted)) {
+ return LazySrcLoc{ .node_offset_initializer = decl.nodeIndexToRelative(init_node) };
+ }
+ }
+ return base_src;
+}
+
/// Called from `performAllTheWork`, after all AstGen workers have finished,
/// and before the main semantic analysis loop begins.
pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {