aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2022-01-08 04:29:49 +0100
committerAndrew Kelley <andrew@ziglang.org>2022-01-08 14:32:40 -0500
commitcc5c25d48b5331396bfa5218dc7f29dff26e20f9 (patch)
tree08767d5933f36d6bc57cc284ed62ac9ca0d625c4
parent4931b8dc93ee4a99a415dffab03d400e95d1a90a (diff)
downloadzig-cc5c25d48b5331396bfa5218dc7f29dff26e20f9.tar.gz
zig-cc5c25d48b5331396bfa5218dc7f29dff26e20f9.zip
stage2: implement @src
-rw-r--r--src/AstGen.zig15
-rw-r--r--src/Module.zig5
-rw-r--r--src/Sema.zig44
-rw-r--r--src/Zir.zig12
-rw-r--r--test/behavior.zig2
5 files changed, 70 insertions, 8 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig
index 7ff3d75682..87cc07fae8 100644
--- a/src/AstGen.zig
+++ b/src/AstGen.zig
@@ -6918,12 +6918,25 @@ fn builtinCall(
return rvalue(gz, rl, result, node);
},
+ .src => {
+ const token_starts = tree.tokens.items(.start);
+ const node_start = token_starts[tree.firstToken(node)];
+
+ astgen.advanceSourceCursor(tree.source, node_start);
+
+ const result = try gz.addExtendedPayload(.builtin_src, Zir.Inst.LineColumn{
+ .line = @intCast(u32, astgen.source_line),
+ .column = @intCast(u32, astgen.source_column),
+ });
+
+ return rvalue(gz, rl, result, node);
+ },
+
.breakpoint => return simpleNoOpVoid(gz, rl, node, .breakpoint),
// zig fmt: off
.This => return rvalue(gz, rl, try gz.addNodeExtended(.this, node), node),
.return_address => return rvalue(gz, rl, try gz.addNodeExtended(.ret_addr, node), node),
- .src => return rvalue(gz, rl, try gz.addNodeExtended(.builtin_src, node), node),
.error_return_trace => return rvalue(gz, rl, try gz.addNodeExtended(.error_return_trace, node), node),
.frame => return rvalue(gz, rl, try gz.addNodeExtended(.frame, node), node),
.frame_address => return rvalue(gz, rl, try gz.addNodeExtended(.frame_address, node), node),
diff --git a/src/Module.zig b/src/Module.zig
index 643e793206..e93fe2549c 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -1663,6 +1663,11 @@ pub const File = struct {
return file.pkg.root_src_directory.join(ally, &[_][]const u8{file.sub_file_path});
}
+ /// Returns the full path to this file relative to its package.
+ pub fn fullPathZ(file: File, ally: Allocator) ![:0]u8 {
+ return file.pkg.root_src_directory.joinZ(ally, &[_][]const u8{file.sub_file_path});
+ }
+
pub fn dumpSrc(file: *File, src: LazySrcLoc) void {
const loc = std.zig.findLineColumn(file.source.bytes, src);
std.debug.print("{s}:{d}:{d}\n", .{ file.sub_file_path, loc.line + 1, loc.column + 1 });
diff --git a/src/Sema.zig b/src/Sema.zig
index bcda9e73ea..aba992d50e 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -9182,8 +9182,50 @@ fn zirBuiltinSrc(
block: *Block,
extended: Zir.Inst.Extended.InstData,
) CompileError!Air.Inst.Ref {
+ const tracy = trace(@src());
+ defer tracy.end();
+
const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
- return sema.fail(block, src, "TODO: implement Sema.zirBuiltinSrc", .{});
+ const extra = sema.code.extraData(Zir.Inst.LineColumn, extended.operand).data;
+ const func = sema.func orelse return sema.fail(block, src, "@src outside function", .{});
+
+ const func_name_val = blk: {
+ var anon_decl = try block.startAnonDecl();
+ defer anon_decl.deinit();
+ const name = std.mem.span(func.owner_decl.name);
+ const bytes = try anon_decl.arena().dupe(u8, name[0 .. name.len + 1]);
+ const new_decl = try anon_decl.finish(
+ try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len - 1),
+ try Value.Tag.bytes.create(anon_decl.arena(), bytes),
+ );
+ break :blk try Value.Tag.decl_ref.create(sema.arena, new_decl);
+ };
+
+ const file_name_val = blk: {
+ var anon_decl = try block.startAnonDecl();
+ defer anon_decl.deinit();
+ const name = try func.owner_decl.getFileScope().fullPathZ(anon_decl.arena());
+ const new_decl = try anon_decl.finish(
+ try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), name.len),
+ try Value.Tag.bytes.create(anon_decl.arena(), name[0 .. name.len + 1]),
+ );
+ break :blk try Value.Tag.decl_ref.create(sema.arena, new_decl);
+ };
+
+ const field_values = try sema.arena.alloc(Value, 4);
+ // file: [:0]const u8,
+ field_values[0] = file_name_val;
+ // fn_name: [:0]const u8,
+ field_values[1] = func_name_val;
+ // line: u32
+ field_values[2] = try Value.Tag.int_u64.create(sema.arena, extra.line + 1);
+ // column: u32,
+ field_values[3] = try Value.Tag.int_u64.create(sema.arena, extra.column + 1);
+
+ return sema.addConstant(
+ try sema.getBuiltinType(block, src, "SourceLocation"),
+ try Value.Tag.@"struct".create(sema.arena, field_values),
+ );
}
fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
diff --git a/src/Zir.zig b/src/Zir.zig
index a7d813cfad..68c1b9df48 100644
--- a/src/Zir.zig
+++ b/src/Zir.zig
@@ -1510,7 +1510,7 @@ pub const Inst = struct {
/// `operand` is `src_node: i32`.
ret_addr,
/// Implements the `@src` builtin.
- /// `operand` is `src_node: i32`.
+ /// `operand` is payload index to `ColumnLine`.
builtin_src,
/// Implements the `@errorReturnTrace` builtin.
/// `operand` is `src_node: i32`.
@@ -2160,10 +2160,7 @@ pub const Inst = struct {
switch_inst: Index,
prong_index: u32,
},
- dbg_stmt: struct {
- line: u32,
- column: u32,
- },
+ dbg_stmt: LineColumn,
/// Used for unary operators which reference an inst,
/// with an AST node source location.
inst_node: struct {
@@ -2964,6 +2961,11 @@ pub const Inst = struct {
token: Ast.TokenIndex,
};
};
+
+ pub const LineColumn = struct {
+ line: u32,
+ column: u32,
+ };
};
pub const SpecialProng = enum { none, @"else", under };
diff --git a/test/behavior.zig b/test/behavior.zig
index 74e76b70a1..64c076e015 100644
--- a/test/behavior.zig
+++ b/test/behavior.zig
@@ -65,6 +65,7 @@ test {
_ = @import("behavior/translate_c_macros.zig");
_ = @import("behavior/try.zig");
_ = @import("behavior/undefined.zig");
+ _ = @import("behavior/src.zig");
if (builtin.zig_backend != .stage2_c) {
// Tests that pass for stage1 and the llvm backend.
@@ -204,7 +205,6 @@ test {
_ = @import("behavior/wasm.zig");
}
_ = @import("behavior/while_stage1.zig");
- _ = @import("behavior/src.zig");
_ = @import("behavior/translate_c_macros_stage1.zig");
}
}