AstGen: fix @export

Make it properly use `std.builtin.ExportOptions`.
This commit is contained in:
Andrew Kelley 2021-04-22 16:07:58 -07:00
parent 130ad08001
commit 3d637e6dd2
5 changed files with 70 additions and 20 deletions

View File

@ -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);
},

View File

@ -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 {

View File

@ -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);

View File

@ -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,

View File

@ -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,