mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
parent
3dddb881bf
commit
03ed3f56cf
53
src/Sema.zig
53
src/Sema.zig
@ -25675,6 +25675,7 @@ fn zirBuiltinExtern(
|
||||
extended: Zir.Inst.Extended.InstData,
|
||||
) CompileError!Air.Inst.Ref {
|
||||
const mod = sema.mod;
|
||||
const ip = &mod.intern_pool;
|
||||
const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
|
||||
const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
|
||||
const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
|
||||
@ -25714,34 +25715,38 @@ fn zirBuiltinExtern(
|
||||
const new_decl = mod.declPtr(new_decl_index);
|
||||
new_decl.name = options.name;
|
||||
|
||||
{
|
||||
const new_var = try mod.intern(.{ .variable = .{
|
||||
.ty = ptr_info.child,
|
||||
.init = .none,
|
||||
.decl = sema.owner_decl_index,
|
||||
.lib_name = options.library_name,
|
||||
.is_extern = true,
|
||||
.is_const = ptr_info.flags.is_const,
|
||||
.is_threadlocal = options.is_thread_local,
|
||||
.is_weak_linkage = options.linkage == .Weak,
|
||||
} });
|
||||
|
||||
new_decl.src_line = sema.owner_decl.src_line;
|
||||
// We only access this decl through the decl_ref with the correct type created
|
||||
// below, so this type doesn't matter
|
||||
new_decl.ty = Type.fromInterned(ptr_info.child);
|
||||
new_decl.val = Value.fromInterned(new_var);
|
||||
new_decl.alignment = .none;
|
||||
new_decl.@"linksection" = .none;
|
||||
new_decl.has_tv = true;
|
||||
new_decl.analysis = .complete;
|
||||
new_decl.generation = mod.generation;
|
||||
}
|
||||
new_decl.src_line = sema.owner_decl.src_line;
|
||||
new_decl.ty = Type.fromInterned(ptr_info.child);
|
||||
new_decl.val = Value.fromInterned(
|
||||
if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn)
|
||||
try ip.getExternFunc(sema.gpa, .{
|
||||
.ty = ptr_info.child,
|
||||
.decl = new_decl_index,
|
||||
.lib_name = options.library_name,
|
||||
})
|
||||
else
|
||||
try mod.intern(.{ .variable = .{
|
||||
.ty = ptr_info.child,
|
||||
.init = .none,
|
||||
.decl = new_decl_index,
|
||||
.lib_name = options.library_name,
|
||||
.is_extern = true,
|
||||
.is_const = ptr_info.flags.is_const,
|
||||
.is_threadlocal = options.is_thread_local,
|
||||
.is_weak_linkage = options.linkage == .Weak,
|
||||
} }),
|
||||
);
|
||||
new_decl.alignment = .none;
|
||||
new_decl.@"linksection" = .none;
|
||||
new_decl.has_tv = true;
|
||||
new_decl.owns_tv = true;
|
||||
new_decl.analysis = .complete;
|
||||
new_decl.generation = mod.generation;
|
||||
|
||||
try sema.ensureDeclAnalyzed(new_decl_index);
|
||||
|
||||
return Air.internedToRef((try mod.getCoerced(Value.fromInterned((try mod.intern(.{ .ptr = .{
|
||||
.ty = switch (mod.intern_pool.indexToKey(ty.toIntern())) {
|
||||
.ty = switch (ip.indexToKey(ty.toIntern())) {
|
||||
.ptr_type => ty.toIntern(),
|
||||
.opt_type => |child_type| child_type,
|
||||
else => unreachable,
|
||||
|
||||
@ -2941,9 +2941,13 @@ pub const Object = struct {
|
||||
const target = owner_mod.resolved_target.result;
|
||||
const sret = firstParamSRet(fn_info, zcu);
|
||||
|
||||
const is_extern = decl.isExtern(zcu);
|
||||
const function_index = try o.builder.addFunction(
|
||||
try o.lowerType(zig_fn_type),
|
||||
try o.builder.string(ip.stringToSlice(try decl.getFullyQualifiedName(zcu))),
|
||||
try o.builder.string(ip.stringToSlice(if (is_extern)
|
||||
decl.name
|
||||
else
|
||||
try decl.getFullyQualifiedName(zcu))),
|
||||
toLlvmAddressSpace(decl.@"addrspace", target),
|
||||
);
|
||||
gop.value_ptr.* = function_index.ptrConst(&o.builder).global;
|
||||
@ -2951,7 +2955,6 @@ pub const Object = struct {
|
||||
var attributes: Builder.FunctionAttributes.Wip = .{};
|
||||
defer attributes.deinit(&o.builder);
|
||||
|
||||
const is_extern = decl.isExtern(zcu);
|
||||
if (!is_extern) {
|
||||
function_index.setLinkage(.internal, &o.builder);
|
||||
function_index.setUnnamedAddr(.unnamed_addr, &o.builder);
|
||||
|
||||
@ -12,3 +12,16 @@ test "anyopaque extern symbol" {
|
||||
}
|
||||
|
||||
export var a_mystery_symbol: i32 = 1234;
|
||||
|
||||
test "function extern symbol" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
|
||||
|
||||
const a = @extern(*const fn () callconv(.C) i32, .{ .name = "a_mystery_function" });
|
||||
try expect(a() == 4567);
|
||||
}
|
||||
|
||||
export fn a_mystery_function() i32 {
|
||||
return 4567;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user