diff --git a/src/AstGen.zig b/src/AstGen.zig index 8ee27b1658..364f76cc7a 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -1336,6 +1336,7 @@ fn blockExprStmts( .dbg_stmt_node, .ensure_result_used, .ensure_result_non_error, + .@"export", .set_eval_branch_quota, .compile_log, .ensure_err_payload_void, @@ -4146,6 +4147,18 @@ fn builtinCall( return rvalue(gz, scope, rl, result, node); }, + .@"export" => { + const target_fn = try expr(gz, scope, .none, params[0]); + // FIXME: When structs work in stage2, actually implement this correctly! + // Currently the name is always signifies Strong linkage. + const export_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]); + _ = try gz.addPlNode(.@"export", node, zir.Inst.Bin{ + .lhs = target_fn, + .rhs = export_name, + }); + return rvalue(gz, scope, rl, .void_value, node); + }, + .add_with_overflow, .align_cast, .align_of, @@ -4175,7 +4188,6 @@ fn builtinCall( .error_name, .error_return_trace, .err_set_cast, - .@"export", .fence, .field_parent_ptr, .float_to_int, diff --git a/src/Sema.zig b/src/Sema.zig index 519d5df401..d2abaaf091 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -342,6 +342,10 @@ pub fn analyzeBody( try sema.zirValidateStructInitPtr(block, inst); continue; }, + .@"export" => { + try sema.zirExport(block, inst); + continue; + }, // Special case instructions to handle comptime control flow. .repeat_inline => { @@ -1333,6 +1337,31 @@ fn analyzeBlockBody( return &merges.block_inst.base; } +fn zirExport(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!void { + const tracy = trace(@src()); + 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 src = inst_data.src(); + + const target_fn = try sema.resolveInst(extra.lhs); + const target_fn_val = try sema.resolveConstValue( + block, + .{ .node_offset_builtin_call_arg0 = inst_data.src_node }, + target_fn, + ); + + const export_name = try sema.resolveConstString( + block, + .{ .node_offset_builtin_call_arg1 = inst_data.src_node }, + extra.rhs, + ); + + const actual_fn = target_fn_val.castTag(.function).?.data; + try sema.mod.analyzeExport(&block.base, src, export_name, actual_fn.owner_decl); +} + fn zirBreakpoint(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!void { const tracy = trace(@src()); defer tracy.end(); diff --git a/src/zir.zig b/src/zir.zig index d3d9d56bfd..ff402a9ddb 100644 --- a/src/zir.zig +++ b/src/zir.zig @@ -328,6 +328,10 @@ pub const Inst = struct { error_union_type, /// `error.Foo` syntax. Uses the `str_tok` field of the Data union. error_value, + /// Exports a function with a specified name. This can be used at comptime + /// to export a function conditionally. + /// Uses the `pl_node` union field. Payload is `Bin`. + @"export", /// Given a pointer to a struct or object that contains virtual fields, returns a pointer /// to the named field. The field name is stored in string_bytes. Used by a.b syntax. /// Uses `pl_node` field. The AST node is the a.b syntax. Payload is Field. @@ -737,6 +741,7 @@ pub const Inst = struct { .elem_val_node, .ensure_result_used, .ensure_result_non_error, + .@"export", .floatcast, .field_ptr, .field_val, @@ -1682,6 +1687,7 @@ const Writer = struct { .xor, .store_node, .error_union_type, + .@"export", .merge_error_sets, .bit_and, .bit_or,