Commit 3d637e6dd2
Changed files (5)
src/AstGen.zig
@@ -6127,15 +6127,18 @@ fn builtinCall(
.c_import => return cImport( gz, scope, rl, node, params[0]),
.@"export" => {
- // TODO: @export is supposed to be able to export things other than functions.
- // Instead of `comptimeExpr` here we need `decl_ref`.
- const fn_to_export = try comptimeExpr(gz, scope, .none, params[0]);
- // TODO: the second parameter here is supposed to be
- // `std.builtin.ExportOptions`, not a string.
- const export_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]);
- _ = try gz.addPlNode(.@"export", node, Zir.Inst.Bin{
- .lhs = fn_to_export,
- .rhs = export_name,
+ const node_tags = tree.nodes.items(.tag);
+ // This function causes a Decl to be exported. The first parameter is not an expression,
+ // but an identifier of the Decl to be exported.
+ if (node_tags[params[0]] != .identifier) {
+ return astgen.failNode(params[0], "the first @export parameter must be an identifier", .{});
+ }
+ const ident_token = main_tokens[params[0]];
+ const decl_name = try gz.identAsString(ident_token);
+ const options = try comptimeExpr(gz, scope, .{ .ty = .export_options_type }, params[1]);
+ _ = try gz.addPlNode(.@"export", node, Zir.Inst.Export{
+ .decl_name = decl_name,
+ .options = options,
});
return rvalue(gz, scope, rl, .void_value, node);
},
src/Sema.zig
@@ -1766,21 +1766,20 @@ fn zirExport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!
defer tracy.end();
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
- const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
+ const extra = sema.code.extraData(Zir.Inst.Export, inst_data.payload_index).data;
const src = inst_data.src();
const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
+ const decl_name = sema.code.nullTerminatedString(extra.decl_name);
+ const decl = try sema.lookupIdentifier(block, lhs_src, decl_name);
+ const options = try sema.resolveInstConst(block, rhs_src, extra.options);
- // TODO (see corresponding TODO in AstGen) this is supposed to be a `decl_ref`
- // instruction, which could reference any decl, which is then supposed to get
- // exported, regardless of whether or not it is a function.
- const target_fn = try sema.resolveInstConst(block, lhs_src, extra.lhs);
- // TODO (see corresponding TODO in AstGen) this is supposed to be
- // `std.builtin.ExportOptions`, not a string.
- const export_name = try sema.resolveConstString(block, rhs_src, extra.rhs);
+ // TODO respect the name, linkage, and section options. Until then we export
+ // as the decl name.
+ _ = options;
+ const export_name = mem.spanZ(decl.name);
- const actual_fn = target_fn.val.castTag(.function).?.data;
- try sema.mod.analyzeExport(&block.base, src, export_name, actual_fn.owner_decl);
+ try sema.mod.analyzeExport(&block.base, src, export_name, decl);
}
fn zirSetAlignStack(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!void {
src/type.zig
@@ -99,6 +99,7 @@ pub const Type = extern union {
.empty_struct_literal,
.@"struct",
.call_options,
+ .export_options,
=> return .Struct,
.enum_full,
@@ -616,6 +617,7 @@ pub const Type = extern union {
.float_mode,
.reduce_op,
.call_options,
+ .export_options,
=> unreachable,
.array_u8,
@@ -794,6 +796,7 @@ pub const Type = extern union {
.float_mode => return writer.writeAll("std.builtin.FloatMode"),
.reduce_op => return writer.writeAll("std.builtin.ReduceOp"),
.call_options => return writer.writeAll("std.builtin.CallOptions"),
+ .export_options => return writer.writeAll("std.builtin.ExportOptions"),
.function => {
const payload = ty.castTag(.function).?.data;
try writer.writeAll("fn(");
@@ -1008,6 +1011,7 @@ pub const Type = extern union {
.float_mode => return Value.initTag(.float_mode_type),
.reduce_op => return Value.initTag(.reduce_op_type),
.call_options => return Value.initTag(.call_options_type),
+ .export_options => return Value.initTag(.export_options_type),
.inferred_alloc_const => unreachable,
.inferred_alloc_mut => unreachable,
else => return Value.Tag.ty.create(allocator, self),
@@ -1065,6 +1069,7 @@ pub const Type = extern union {
.float_mode,
.reduce_op,
.call_options,
+ .export_options,
=> true,
.@"struct" => {
@@ -1175,6 +1180,7 @@ pub const Type = extern union {
.float_mode,
.reduce_op,
.call_options,
+ .export_options,
=> return 1,
.fn_noreturn_no_args, // represents machine code; not a pointer
@@ -1352,6 +1358,7 @@ pub const Type = extern union {
.float_mode,
.reduce_op,
.call_options,
+ .export_options,
=> return 1,
.array_u8 => self.castTag(.array_u8).?.data,
@@ -1615,6 +1622,7 @@ pub const Type = extern union {
.float_mode,
.reduce_op,
.call_options,
+ .export_options,
=> @panic("TODO at some point we gotta resolve builtin types"),
};
}
@@ -2238,6 +2246,7 @@ pub const Type = extern union {
.float_mode,
.reduce_op,
.call_options,
+ .export_options,
=> return null,
.@"struct" => {
@@ -2403,6 +2412,7 @@ pub const Type = extern union {
.float_mode,
.reduce_op,
.call_options,
+ .export_options,
=> @panic("TODO resolve std.builtin types"),
else => unreachable,
@@ -2425,6 +2435,7 @@ pub const Type = extern union {
.float_mode,
.reduce_op,
.call_options,
+ .export_options,
=> @panic("TODO resolve std.builtin types"),
else => unreachable,
}
@@ -2446,6 +2457,7 @@ pub const Type = extern union {
.float_mode,
.reduce_op,
.call_options,
+ .export_options,
=> @panic("TODO resolve std.builtin types"),
else => unreachable,
}
@@ -2489,6 +2501,7 @@ pub const Type = extern union {
.float_mode,
.reduce_op,
.call_options,
+ .export_options,
=> @panic("TODO resolve std.builtin types"),
else => unreachable,
}
@@ -2518,6 +2531,7 @@ pub const Type = extern union {
.float_mode,
.reduce_op,
.call_options,
+ .export_options,
=> @panic("TODO resolve std.builtin types"),
else => unreachable,
}
@@ -2548,6 +2562,7 @@ pub const Type = extern union {
.float_mode,
.reduce_op,
.call_options,
+ .export_options,
=> @panic("TODO resolve std.builtin types"),
else => unreachable,
}
@@ -2587,6 +2602,7 @@ pub const Type = extern union {
.float_mode,
.reduce_op,
.call_options,
+ .export_options,
=> @panic("TODO resolve std.builtin types"),
else => unreachable,
@@ -2643,6 +2659,7 @@ pub const Type = extern union {
float_mode,
reduce_op,
call_options,
+ export_options,
@"null",
@"undefined",
fn_noreturn_no_args,
@@ -2754,6 +2771,7 @@ pub const Type = extern union {
.float_mode,
.reduce_op,
.call_options,
+ .export_options,
=> @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),
.array_u8,
src/value.zig
@@ -72,6 +72,7 @@ pub const Value = extern union {
float_mode_type,
reduce_op_type,
call_options_type,
+ export_options_type,
undef,
zero,
@@ -185,6 +186,7 @@ pub const Value = extern union {
.float_mode_type,
.reduce_op_type,
.call_options_type,
+ .export_options_type,
=> @compileError("Value Tag " ++ @tagName(t) ++ " has no payload"),
.int_big_positive,
@@ -351,6 +353,7 @@ pub const Value = extern union {
.float_mode_type,
.reduce_op_type,
.call_options_type,
+ .export_options_type,
=> unreachable,
.ty => {
@@ -506,6 +509,7 @@ pub const Value = extern union {
.float_mode_type => return out_stream.writeAll("std.builtin.FloatMode"),
.reduce_op_type => return out_stream.writeAll("std.builtin.ReduceOp"),
.call_options_type => return out_stream.writeAll("std.builtin.CallOptions"),
+ .export_options_type => return out_stream.writeAll("std.builtin.ExportOptions"),
.abi_align_default => return out_stream.writeAll("(default ABI alignment)"),
.empty_struct_value => return out_stream.writeAll("struct {}{}"),
@@ -635,6 +639,7 @@ pub const Value = extern union {
.float_mode_type => Type.initTag(.float_mode),
.reduce_op_type => Type.initTag(.reduce_op),
.call_options_type => Type.initTag(.call_options),
+ .export_options_type => Type.initTag(.export_options),
.int_type => {
const payload = self.castTag(.int_type).?.data;
@@ -1181,6 +1186,7 @@ pub const Value = extern union {
.float_mode_type,
.reduce_op_type,
.call_options_type,
+ .export_options_type,
=> @panic("TODO this hash function looks pretty broken. audit it"),
}
return hasher.final();
@@ -1336,6 +1342,7 @@ pub const Value = extern union {
.float_mode_type,
.reduce_op_type,
.call_options_type,
+ .export_options_type,
=> true,
.zero,
src/Zir.zig
@@ -1352,6 +1352,7 @@ pub const Inst = struct {
float_mode_type,
reduce_op_type,
call_options_type,
+ export_options_type,
/// `undefined` (untyped)
undef,
@@ -1575,6 +1576,10 @@ pub const Inst = struct {
.ty = Type.initTag(.type),
.val = Value.initTag(.call_options_type),
},
+ .export_options_type = .{
+ .ty = Type.initTag(.type),
+ .val = Value.initTag(.export_options_type),
+ },
.undef = .{
.ty = Type.initTag(.@"undefined"),
@@ -2214,6 +2219,12 @@ pub const Inst = struct {
src_node: i32,
};
+ pub const Export = struct {
+ /// Null-terminated string index.
+ decl_name: u32,
+ options: Ref,
+ };
+
/// Trailing: `CompileErrors.Item` for each `items_len`.
pub const CompileErrors = struct {
items_len: u32,
@@ -2451,7 +2462,6 @@ const Writer = struct {
.xor,
.store_node,
.error_union_type,
- .@"export",
.merge_error_sets,
.bit_and,
.bit_or,
@@ -2479,6 +2489,8 @@ const Writer = struct {
.bitcast_result_ptr,
=> try self.writePlNodeBin(stream, inst),
+ .@"export" => try self.writePlNodeExport(stream, inst),
+
.call,
.call_chkused,
.call_compile_time,
@@ -2729,6 +2741,17 @@ const Writer = struct {
try self.writeSrc(stream, inst_data.src());
}
+ fn writePlNodeExport(self: *Writer, stream: anytype, inst: Inst.Index) !void {
+ const inst_data = self.code.instructions.items(.data)[inst].pl_node;
+ const extra = self.code.extraData(Inst.Export, inst_data.payload_index).data;
+ const decl_name = self.code.nullTerminatedString(extra.decl_name);
+
+ try stream.print("{}, ", .{std.zig.fmtId(decl_name)});
+ try self.writeInstRef(stream, extra.options);
+ try stream.writeAll(") ");
+ try self.writeSrc(stream, inst_data.src());
+ }
+
fn writePlNodeErrorSetDecl(self: *Writer, stream: anytype, inst: Inst.Index) !void {
const inst_data = self.code.instructions.items(.data)[inst].pl_node;
const extra = self.code.extraData(Inst.ErrorSetDecl, inst_data.payload_index);