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