zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 458943e324e81762a9a2aa839d2fa3c851068e6f (tree)
parent ed63d6c7fdbdc3c508457ca792436595dd443ac8
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Tue, 10 May 2022 22:04:30 -0400

Merge pull request #9831 from mathetake/llvmvisibility

Stage1: Add Visibility field to ExportOptions.
Diffstat:
Mlib/std/builtin.zig | 9+++++++++
Msrc/Sema.zig | 29++++++++++++++++++++++-------
Msrc/codegen/llvm.zig | 5+++++
Msrc/codegen/llvm/bindings.zig | 9+++++++++
4 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig @@ -70,6 +70,14 @@ pub const GlobalLinkage = enum { /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. +pub const SymbolVisibility = enum { + default, + hidden, + protected, +}; + +/// This data structure is used by the Zig language code generation and +/// therefore must be kept in sync with the compiler implementation. pub const AtomicOrder = enum { Unordered, Monotonic, @@ -655,6 +663,7 @@ pub const ExportOptions = struct { name: []const u8, linkage: GlobalLinkage = .Strong, section: ?[]const u8 = null, + visibility: SymbolVisibility = .default, }; /// This data structure is used by the Zig language code generation and diff --git a/src/Sema.zig b/src/Sema.zig @@ -4348,6 +4348,7 @@ pub fn analyzeExport( .name = symbol_name, .linkage = borrowed_options.linkage, .section = section, + .visibility = borrowed_options.visibility, }, .src = src, .link = switch (mod.comp.bin_file.tag) { @@ -14998,23 +14999,37 @@ fn resolveExportOptions( const air_ref = sema.resolveInst(zir_ref); const options = try sema.coerce(block, export_options_ty, air_ref, src); - const name = try sema.fieldVal(block, src, options, "name", src); - const name_val = try sema.resolveConstValue(block, src, name); + const name_operand = try sema.fieldVal(block, src, options, "name", src); + const name_val = try sema.resolveConstValue(block, src, name_operand); + const name_ty = Type.initTag(.const_slice_u8); + const name = try name_val.toAllocatedBytes(name_ty, sema.arena, sema.mod); - const linkage = try sema.fieldVal(block, src, options, "linkage", src); - const linkage_val = try sema.resolveConstValue(block, src, linkage); + const linkage_operand = try sema.fieldVal(block, src, options, "linkage", src); + const linkage_val = try sema.resolveConstValue(block, src, linkage_operand); + const linkage = linkage_val.toEnum(std.builtin.GlobalLinkage); const section = try sema.fieldVal(block, src, options, "section", src); const section_val = try sema.resolveConstValue(block, src, section); + const visibility_operand = try sema.fieldVal(block, src, options, "visibility", src); + const visibility_val = try sema.resolveConstValue(block, src, visibility_operand); + const visibility = visibility_val.toEnum(std.builtin.SymbolVisibility); + + if (visibility != .default and linkage == .Internal) { + return sema.fail(block, src, "symbol '{s}' exported with internal linkage has non-default visibility {s}", .{ + name, @tagName(visibility), + }); + } + if (!section_val.isNull()) { return sema.fail(block, src, "TODO: implement exporting with linksection", .{}); } - const name_ty = Type.initTag(.const_slice_u8); + return std.builtin.ExportOptions{ - .name = try name_val.toAllocatedBytes(name_ty, sema.arena, sema.mod), - .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage), + .name = name, + .linkage = linkage, .section = null, // TODO + .visibility = visibility, }; } diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig @@ -808,6 +808,11 @@ pub const Object = struct { .Weak => llvm_global.setLinkage(.WeakODR), .LinkOnce => llvm_global.setLinkage(.LinkOnceODR), } + switch (exports[0].options.visibility) { + .default => llvm_global.setVisibility(.Default), + .hidden => llvm_global.setVisibility(.Hidden), + .protected => llvm_global.setVisibility(.Protected), + } if (decl.val.castTag(.variable)) |variable| { if (variable.data.is_threadlocal) { llvm_global.setThreadLocalMode(.GeneralDynamicTLSModel); diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig @@ -117,6 +117,9 @@ pub const Value = opaque { pub const setLinkage = LLVMSetLinkage; extern fn LLVMSetLinkage(Global: *const Value, Linkage: Linkage) void; + pub const setVisibility = LLVMSetVisibility; + extern fn LLVMSetVisibility(Global: *const Value, Linkage: Visibility) void; + pub const setUnnamedAddr = LLVMSetUnnamedAddr; extern fn LLVMSetUnnamedAddr(Global: *const Value, HasUnnamedAddr: Bool) void; @@ -1324,6 +1327,12 @@ pub const Linkage = enum(c_uint) { LinkerPrivateWeak, }; +pub const Visibility = enum(c_uint) { + Default, + Hidden, + Protected, +}; + pub const ThreadLocalMode = enum(c_uint) { NotThreadLocal, GeneralDynamicTLSModel,